8

我正在使用 java.util.Scanner 使用以下代码从类路径中读取文件内容:

String path1 = getClass().getResource("/myfile.html").getFile();

System.out.println(new File(path1).length()); // 22244 (correct)

String file1 = new Scanner(new File(path1)).useDelimiter("\\Z").next();
System.out.println(file1.length()); // 2048 (first 2k only)

代码从idea用命令运行(maven测试)

/Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/bin/java -Dmaven.home=/usr/share/java/maven-3.0.4 -Dclassworlds.conf=/usr/share/java/maven-3.0.4/bin/m2.conf -Didea.launcher.port=7533 "-Didea.launcher.bin.path=/Applications/IntelliJ IDEA 12 CE.app/bin" -Dfile.encoding=UTF-8 -classpath "/usr/share/java/maven-3.0.4/boot/plexus-classworlds-2.4.jar:/Applications/IntelliJ IDEA 12 CE.app/lib/idea_rt.jar" com.intellij.rt.execution.application.AppMain org.codehaus.classworlds.Launcher --fail-fast --strict-checksums test

它在我的win7机器上完美运行。但是在我搬到 mac 之后,同样的测试失败了。我试图谷歌但没有找到太多=(

为什么带分隔符 \Z 的扫描仪在 win7 上将我的整个文件读入字符串,但在 mac 上却不这样做?我知道有更多的方法可以读取文件,但我喜欢这种单线并想了解它为什么不起作用。谢谢。

4

3 回答 3

2

这是来自java的一些信息

http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html

\Z 输入的结尾,但对于最后的终止符,如果有的话

\z 输入结束

线路终结器

行终止符是一个或两个字符的序列,用于标记输入字符序列的一行的结尾。以下被认为是线路终止符:

一个换行符('\n'),一个回车符紧跟一个换行符(“\r\n”),一个独立的回车符('\r'),一个下一个-行字符 ('\u0085')、行分隔符 ('\u2028') 或段落分隔符 ('\u2029)。

所以使用\z而不是\Z

于 2013-06-26T06:16:03.677 回答
1

有一篇关于这种完全读取文件的方法的好文章Scanner

http://closurebraces.net/2011/12/17/scanner-with-z-regex/

简单来说:

因为以“/z”作为分隔符的单次读取应该读取所​​有内容,直到“输入结束”,所以很容易只执行一次读取并保留它,就像上面列出的示例一样。

在大多数情况下没关系,但我发现至少有一种情况是读取“输入结束”并不会读取整个输入——当输入是 SequenceInputStream 时,每个组成 InputStream 似乎都会给出一个单独的“结束”自己的输入”。因此,如果您使用分隔符“/z”进行单次读取,它将返回 SequenceInputStream 的第一个组成流的内容,但不会读入其余的组成流。

小心使用它。最好逐行阅读,或者使用hasNext()检查直到它是真实的false

UPD:换句话说,试试这个代码:

StringBuilder file1 = new StringBuilder();
Scanner scanner = new Scanner(new File(path1)).useDelimiter("\\Z");

while (scanner.hasNext()) {
   file1.append(scanner.next());
}
于 2013-06-26T06:13:38.643 回答
1

我在 Mac 上使用 Java 7 update 45 时也遇到了这种情况nextLine()。更糟糕的是,在超过 2048 字节的行之后,文件的其余部分被忽略,扫描仪认为它已经是文件的结尾。

我将其更改为明确告诉 Scanner 使用更大的缓冲区,并且它可以工作。

Scanner sc = new Scanner(new BufferedInputStream(new FileInputStream(nf), 20*1024*1024), "utf-8");
于 2014-02-04T09:03:06.357 回答