web-dev-qa-db-ja.com

WindowsでJavaでファイルが空かどうかを確認する最も効率的な方法

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!");
25
GPX

ファイルの最初の行が空かどうかを確認します。

BufferedReader br = new BufferedReader(new FileReader("path_to_some_file"));     
if (br.readLine() == null) {
    System.out.println("No errors, and file empty");
}
42
Victor Carmouze

なぜ単に使用しないのですか:

File file = new File("test.txt");

if (file.length() == 0) {
    // file empty
} else {
    // not empty
}

それに何か問題がありますか?

19
SneakyMummin

これは、サイズが大きすぎるファイル(使用可能なメモリを超える)が例外をスローするという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());
    }        
}
2
Manuel

FileReaderのアプローチを試してみることもできますが、まだgiveめる時間ではないかもしれません。 BOMフィールドが破壊されている場合は、stackoverflowに投稿されたこのソリューションを試してください。

バイトオーダーマークがJavaでのファイル読み取りを台無しにする

2
Farmor

これを行う別の方法は(Apache CommonsFileUtils)-

private void printEmptyFileName(final File file) throws IOException {
    if (FileUtils.readFileToString(file).trim().isEmpty()) {
        System.out.println("File is empty: " + file.getName());
    }        
}
1
Saikat Sengupta
String line = br.readLine();
String[] splitted = line.split("anySplitCharacter");
if(splitted.length == 0)
    //file is empty
else
    //file is not empty

テキストファイルでも同じ問題が発生しました。空でしたが、readLineメソッドによって返される値はnullではありませんでした。そのため、データの分割された属性にアクセスするために使用していたString配列にその値を割り当てようとしました。うまくいきました。これを試してみて、それがあなたにもうまくいくかどうか教えてください。

1
crazyDeveloper

FileReaderを試してください。このリーダーは文字のストリームを読み取るためのものであり、FileInputStreamは生データを読み取るためのものです。

Javadocから:

FileReaderは、文字のストリームを読み取るためのものです。生バイトのストリームを読み取るには、FileInputStreamの使用を検討してください。

ログファイルを読みたいので、FileReaderはIMOを使用するクラスです。

1
Cygnusx1

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!!");  
}  

更新:最初の回答は時期尚早で、バグが含まれていました。

0
Farmor

最初のスニペットのアイデアは正しいです。おそらくiByteCount == -1:ファイルhas少なくとも1バイトかどうか:

if (iByteCount == -1)  
    System.out.println("NO ERRORS!");
else
    System.out.println("SOME ERRORS!");
0
Nivas

現在、これらのメソッドは両方とも、ログファイルが空(コンテンツがない)の場合に失敗しますが、ファイルサイズはゼロ(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バイトだけを読むか、またはその両方を行うことで、より良い結果が得られます。ただし、問題は次のとおりです。

  • ファイルサイズをテストし、最初の数バイトを読み取った場合、2回のsyscallを実行しています。
  • 実際の回線終了シーケンスは、プラットフォームに応じて、CR、NL、またはCR NLになります。 (これはWindows向けだと言っていますが、アプリケーションを移植する必要がある場合はどうなりますか?または、誰かがWindows以外のファイルを送信した場合はどうなりますか?)
  • ストリーム/リーダースタックの設定を避けるのは良いことですが、ファイルの文字エンコーディングcouldは、CRおよびNLをバイト_0x0d_および_0x0a_以外にマップします。 (たとえば... UTF-16)
  • それから、いくつかのWindowsユーティリティには、BOMマーカーをUTF-8エンコードファイルに入れるという厄介な習慣があります。 (これは上記の簡単なバージョンを台無しにすることさえあります!)

このすべては、最も効率的な解決策がかなり複雑になることを意味します。

0
Stephen C

すべての可能性をカバーするために、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");
}
0
user3649959

file.length == 0を使用するのが最善の方法だと思います。

最初の行が空である可能性があります。

0
user3744089