it-swarm.com.de

Die effizienteste Methode, um zu überprüfen, ob eine Datei in Java unter Windows leer ist

Ich versuche zu prüfen, ob eine Protokolldatei leer ist (keine Fehler bedeutet) oder nicht, in Java oder unter Windows. Ich habe bisher 2 Methoden ausprobiert.

Methode 1 (Fehler)

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

Methode 2 (Fehler)

File logFile = new File(sLogFilename);
if(logFile.length() == 0)
    System.out.println("NO ERRORS!");
else
    System.out.println("SOME ERRORS!");

Diese beiden Methoden schlagen jetzt zu Zeiten fehl, wenn die Protokolldatei leer ist (ohne Inhalt), die Dateigröße jedoch nicht Null ist (2 Byte).

Was ist die effizienteste und- genaue Methode, um zu überprüfen, ob die Datei leer ist? Ich habe um Effizienz gebeten, da ich die Dateigröße tausende Male in einer Schleife überprüfen muss.

Hinweis: Die Dateigröße bewegt sich nur um wenige bis 10 KB.

Methode 3 (Fehler)

Dem Vorschlag von @ Cygnusx1 folgend hatte ich versucht, eine FileReader zu verwenden, ohne Erfolg. Hier ist der Ausschnitt, wenn jemand interessiert ist.

Reader reader = new FileReader(sLogFilename);
int readSize = reader.read();
if (readSize == -1)
    System.out.println("NO ERRORS!");
else
    System.out.println("SOME ERRORS!");
24
GPX

Prüfen Sie, ob die erste Zeile der Datei leer ist:

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

Warum nicht einfach verwenden:

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

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

Stimmt etwas nicht?

16
SneakyMummin

Dies ist eine Verbesserung der Antwort von Saik0 basierend auf Anwar Shaikhs Kommentar, dass zu große Dateien (oberhalb des verfügbaren Speichers) eine Ausnahme auslösen:

Verwenden von 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

Sie können den FileReader-Ansatz ausprobieren, es ist jedoch möglicherweise noch nicht an der Zeit aufzugeben ... Wenn das BOM-Feld für Sie zerstört wird, probieren Sie diese Lösung, die hier bei stackoverflow bereitgestellt wird.

Byte-Reihenfolge markiert das Lesen von Dateien in Java

2
Farmor

Eine andere Möglichkeit, dies zu tun, ist (mit 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
String line = br.readLine();
String[] splitted = line.split("anySplitCharacter");
if(splitted.length == 0)
    //file is empty
else
    //file is not empty

Ich hatte das gleiche Problem mit meiner Textdatei. Obwohl es leer war, war der von der readLine-Methode zurückgegebene Wert nicht null. Daher habe ich versucht, den Wert dem String-Array zuzuweisen, mit dem ich auf die aufgeteilten Attribute meiner Daten zugreifen wollte. Es hat für mich funktioniert. Probieren Sie es aus und sagen Sie mir, ob es auch für Sie funktioniert.

1
crazyDeveloper

Versuchen Sie FileReader, dieser Reader soll den Zeichenstrom lesen, während FileInputStream Rohdaten lesen soll.

Aus dem Javadoc:

FileReader ist zum Lesen von Zeichenströmen gedacht. Zum Lesen Streams von rohen Bytes, sollten Sie einen FileInputStream verwenden.

Da Sie eine Protokolldatei lesen möchten, ist FileReader die Klasse, die IMO verwendet.

1
Cygnusx1

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

Aktualisiert: Meine erste Antwort war verfrüht und enthielt einen Fehler.

0
Farmor

Die Idee Ihres ersten Snippets ist richtig. Wahrscheinlich wollten Sie iByteCount == -1 überprüfen, ob die Datei hat mindestens ein Byte hat:

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

Diese beiden Methoden schlagen jetzt zu Zeiten fehl, wenn die Protokolldatei leer ist (ohne Inhalt), die Dateigröße jedoch nicht Null ist (2 Byte).

Ich denke, Sie werden feststellen, dass die Datei NICHT leer ist. Ich denke eher, dass Sie feststellen werden, dass diese beiden Charaktere ein CR und ein NL sind. die Datei besteht aus einer Zeile, die leer ist.

Wenn Sie testen möchten, ob eine Datei leer ist oder nur eine einzige leere Zeile hat, können Sie dies auf einfache und relativ effiziente Weise tun:

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

Können wir das effizienter machen? Möglicherweise. Es hängt davon ab, wie oft Sie mit den drei verschiedenen Fällen umgehen müssen:

  • eine völlig leere Datei
  • eine Datei, die aus einer einzelnen leeren Zeile besteht
  • eine Datei mit einer nicht leeren Zeile oder mehreren Zeilen.

Sie können es wahrscheinlich besser machen, indem Sie Files.length() verwenden und/oder nur die ersten zwei Bytes lesen. Zu den Problemen gehören jedoch:

  • Wenn Sie beide die Dateigröße testen UND die ersten paar Bytes lesen, machen Sie zwei Syscalls.
  • Die tatsächliche Leitungsbeendigungssequenz kann je nach Plattform CR, NL oder CR NL sein. (Ich weiß, Sie sagen, dies ist für Windows, aber was passiert, wenn Sie Ihre Anwendung portieren müssen? Oder wenn Ihnen jemand eine Nicht-Windows-Datei schickt?)
  • Es wäre schön zu vermeiden, das Stream/Reader-Stack einzurichten, aber die Zeichencodierung der Datei könnte CR und NL auf etwas anderes als die Bytes 0x0d und 0x0a legen. (Zum Beispiel ... UTF-16)
  • Außerdem gibt es die lästige Angewohnheit einiger Windows-Dienstprogramme, BOM-Markierungen in UTF-8-kodierte Dateien zu setzen. (Dies würde sogar die einfache Version oben durcheinander bringen!)

All dies bedeutet, dass die effizienteste Lösung ziemlich kompliziert sein wird.

0
Stephen C

Ich habe die beiden besten Lösungen kombiniert, um alle Möglichkeiten abzudecken:

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

Ich denke, der beste Weg ist, file.length == 0 zu verwenden.

Es ist manchmal möglich, dass die erste Zeile leer ist.

0
user3744089