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)

コードはコマンドでアイデアから実行されます (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 入力の終わり

行末記号

行終端記号は、入力文字シーケンスの行の終わりを示す 1 文字または 2 文字のシーケンスです。以下は改行文字として認識されます。

改行 (改行) 文字 ('\n')、直後に改行文字が続く改行文字 ("\r\n")、スタンドアロンの改行文字 ('\r')、次の-行文字 ('\u0085')、行区切り文字 ('\u2028')、または段落区切り文字 ('\u2029')。

したがって、\z代わりに使用します\Z

于 2013-06-26T06:16:03.677 に答える
1

でファイルを完全に読み取るこの方法に関する良い記事がありますScanner

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

簡単に言えば:

区切り文字として「/z」を使用した 1 回の読み取りでは、「入力の最後」まですべてを読み取る必要があるため、上記の例のように、1 回の読み取りだけを実行してそのままにしておくのは魅力的です。

ほとんどの場合は問題ありませんが、「入力の最後」まで読み取っても入力全体が読み取られない状況が少なくとも 1 つあります。独自の「入力の」。その結果、区切り文字「/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 に答える