JavaでWindowsのログファイルが空(エラーなし)かどうかを確認しようとしています。これまでに2つの方法を試してみました。
方法1(失敗)
FileInputStream fis = new FileInputStream(new File(sLogFilename));
int iByteCount = fis.read();
if (iByteCount == -1)
System.out.println("NO ERRORS!");
else
System.out.println("SOME ERRORS!");
方法2(失敗)
File logFile = new File(sLogFilename);
if(logFile.length() == 0)
System.out.println("NO ERRORS!");
else
System.out.println("SOME ERRORS!");
現在、これらのメソッドは両方とも、ログファイルが空(コンテンツがない)の場合に失敗しますが、ファイルサイズはゼロ(2バイト)ではありません。
ファイルが空かどうかをチェックする最も効率的なおよび正確な方法は何ですか?ループで何千回もファイルサイズをチェックし続ける必要があるため、効率を求めました。
注:ファイルサイズは、数KBから10 KB程度の範囲で推移します!
方法3(失敗)
@ Cygnusx1の提案に従って、FileReader
も使用しようとしましたが、成功しませんでした。誰かが興味を持っているなら、これがスニペットです。
Reader reader = new FileReader(sLogFilename);
int readSize = reader.read();
if (readSize == -1)
System.out.println("NO ERRORS!");
else
System.out.println("SOME ERRORS!");
ファイルの最初の行が空かどうかを確認します。
BufferedReader br = new BufferedReader(new FileReader("path_to_some_file"));
if (br.readLine() == null) {
System.out.println("No errors, and file empty");
}
なぜ単に使用しないのですか:
File file = new File("test.txt");
if (file.length() == 0) {
// file empty
} else {
// not empty
}
それに何か問題がありますか?
これは、サイズが大きすぎるファイル(使用可能なメモリを超える)が例外をスローするというAnwar Shaikhのコメントに基づくSaik0の回答の改善です。
Apache Commons FileUtilsを使用する
private void printEmptyFileName(final File file) throws IOException {
/*Arbitrary big-ish number that definitely is not an empty file*/
int limit = 4096;
if(file.length < limit && FileUtils.readFileToString(file).trim().isEmpty()) {
System.out.println("File is empty: " + file.getName());
}
}
FileReaderのアプローチを試してみることもできますが、まだgiveめる時間ではないかもしれません。 BOMフィールドが破壊されている場合は、stackoverflowに投稿されたこのソリューションを試してください。
これを行う別の方法は(Apache Commons
FileUtils
)-
private void printEmptyFileName(final File file) throws IOException {
if (FileUtils.readFileToString(file).trim().isEmpty()) {
System.out.println("File is empty: " + file.getName());
}
}
String line = br.readLine();
String[] splitted = line.split("anySplitCharacter");
if(splitted.length == 0)
//file is empty
else
//file is not empty
テキストファイルでも同じ問題が発生しました。空でしたが、readLineメソッドによって返される値はnullではありませんでした。そのため、データの分割された属性にアクセスするために使用していたString配列にその値を割り当てようとしました。うまくいきました。これを試してみて、それがあなたにもうまくいくかどうか教えてください。
FileReader
を試してください。このリーダーは文字のストリームを読み取るためのものであり、FileInputStream
は生データを読み取るためのものです。
Javadocから:
FileReaderは、文字のストリームを読み取るためのものです。生バイトのストリームを読み取るには、FileInputStreamの使用を検討してください。
ログファイルを読みたいので、FileReader
はIMOを使用するクラスです。
http://www.coderanch.com/t/279224/Streams/Java/Checking-empty-file から盗まれた
FileInputStream fis = new FileInputStream(new File("file_name"));
int b = fis.read();
if (b == -1)
{
System.out.println("!!File " + file_name + " emty!!");
}
更新:最初の回答は時期尚早で、バグが含まれていました。
最初のスニペットのアイデアは正しいです。おそらくiByteCount == -1
:ファイルhas少なくとも1バイトかどうか:
if (iByteCount == -1)
System.out.println("NO ERRORS!");
else
System.out.println("SOME ERRORS!");
現在、これらのメソッドは両方とも、ログファイルが空(コンテンツがない)の場合に失敗しますが、ファイルサイズはゼロ(2バイト)ではありません。
実際、ファイルが空ではないことがわかると思います。むしろ、これらの2つの文字がCRとNLであることがわかると思います。つまり、ファイルは空の1行で構成されます。
ファイルが空であるか単一の空行があるかをテストする場合、単純で比較的効率的な方法は次のとおりです。
_try (BufferedReader br = new BufferedReader(FileReader(fileName))) {
String line = br.readLine();
if (line == null ||
(line.length() == 0 && br.readLine() == null)) {
System.out.println("NO ERRORS!");
} else {
System.out.println("SOME ERRORS!");
}
}
_
これをもっと効率的にできますか?おそらく。それは、次の3つの異なるケースに対処する頻度に依存します。
おそらく、Files.length()
を使用するか、最初の2バイトだけを読むか、またはその両方を行うことで、より良い結果が得られます。ただし、問題は次のとおりです。
0x0d
_および_0x0a
_以外にマップします。 (たとえば... UTF-16)このすべては、最も効率的な解決策がかなり複雑になることを意味します。
すべての可能性をカバーするために、2つの最適なソリューションを組み合わせました。
BufferedReader br = new BufferedReader(new FileReader(fileName));
File file = new File(fileName);
if (br.readLine() == null && file.length() == 0)
{
System.out.println("No errors, and file empty");
}
else
{
System.out.println("File contains something");
}
file.length == 0
を使用するのが最善の方法だと思います。
最初の行が空である可能性があります。