web-dev-qa-db-fra.com

Le moyen le plus efficace de vérifier si un fichier est vide en Java sous Windows

J'essaie de vérifier si un fichier journal est vide (c'est-à-dire sans erreur) ou non, sous Java, sous Windows. J'ai essayé d'utiliser 2 méthodes jusqu'à présent.

Méthode 1 (échec)

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

Méthode 2 (échec)

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

Désormais, ces deux méthodes échouent lorsque le fichier journal est vide (sans contenu), mais que la taille du fichier n’est pas nulle (2 octets).

Quelle est la méthode la plus efficace et pour vérifier si le fichier est vide? J'ai demandé l'efficacité, car je dois vérifier en boucle la taille du fichier des milliers de fois.

Remarque: La taille du fichier ne devrait fluctuer que de quelques dizaines à 10 Ko seulement!

Méthode 3 (échec)

Suivant la suggestion de @ Cygnusx1, j’avais aussi essayé d’utiliser une variable FileReader, sans succès. Voici l'extrait, si quelqu'un est intéressé.

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

Vérifiez si la première ligne du fichier est vide:

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

Pourquoi ne pas simplement utiliser:

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

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

Y at-il quelque chose qui cloche avec ça?

16
SneakyMummin

Ceci est une amélioration de la réponse de Saik0 basée sur le commentaire d'Anwar Shaikh selon lequel les fichiers trop volumineux (au-dessus de la mémoire disponible) génèrent une exception:

Utiliser 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

Vous pouvez choisir d’essayer l’approche FileReader mais il n’est peut-être pas temps d’abandonner pour le moment . Si le champ de nomenclature vous détruit, essayez cette solution publiée ici à stackoverflow.

L'ordre des octets bousille la lecture des fichiers en Java

2
Farmor

Une autre façon de faire est d'utiliser (en utilisant 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

J'ai eu le même problème avec mon fichier texte. Bien qu'elle soit vide, la valeur renvoyée par la méthode readLine n'était pas null. Par conséquent, j'ai essayé d'assigner sa valeur au tableau String que j'utilisais pour accéder aux attributs fractionnés de mes données. Cela a fonctionné pour moi. Essayez ceci et dites-moi si cela fonctionne pour vous aussi.

1
crazyDeveloper

Essayez FileReader, ce lecteur est censé lire le flux de caractères, alors que FileInputStream est destiné à lire les données brutes.

De la Javadoc:

FileReader est destiné à la lecture de flux de caractères. A lire flux d’octets bruts, envisagez d’utiliser un FileInputStream.

Puisque vous voulez lire un fichier journal, FileReader est la classe qui utilise IMO.

1
Cygnusx1

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

Mise à jour: Ma première réponse était prématurée et contenait un bug.

0
Farmor

L'idée de votre premier extrait est juste. Vous vouliez probablement vérifier iByteCount == -1: si le fichier a au moins un octet:

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

Désormais, ces deux méthodes échouent lorsque le fichier journal est vide (sans contenu), mais que la taille du fichier n’est pas nulle (2 octets).

En fait, je pense que vous constaterez que le fichier n’est PAS vide. Je pense plutôt que vous constaterez que ces deux personnages sont un CR et un NL; c'est-à-dire que le fichier est constitué d'une ligne vide.

Si vous voulez vérifier si un fichier est vide ou s'il contient une seule ligne vide, voici une méthode simple et relativement efficace:

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

Peut-on faire cela plus efficacement? Peut-être. Cela dépend de la fréquence à laquelle vous devez traiter les trois cas différents:

  • un fichier complètement vide
  • un fichier constitué d'une seule ligne vide
  • un fichier avec une ligne non vide ou plusieurs lignes.

Vous pouvez probablement faire mieux en utilisant Files.length() et/ou en lisant uniquement les deux premiers octets. Cependant, les problèmes incluent:

  • Si vous testez tous deux la taille du fichier ET lisez les quelques premiers octets, vous effectuez 2 appels système.
  • La séquence réelle de terminaison de ligne peut être CR, NL ou CR NL, en fonction de la plate-forme. (Je sais que vous dites que c'est pour Windows, mais que se passe-t-il si vous devez transférer votre application? Ou si quelqu'un vous envoie un fichier autre que Windows?)
  • Il serait bien d'éviter de configurer une pile de lecteurs/flux, mais l'encodage de caractères du fichier pourrait mapper CR et NL sur autre chose que les octets 0x0d et 0x0a. (Par exemple ... UTF-16)
  • Il y a aussi la fâcheuse habitude de certains utilitaires Windows de placer les marqueurs de nomenclature dans des fichiers codés UTF-8. (Cela pourrait même gâcher la version simple ci-dessus!)

Tout cela signifie que la solution la plus efficace possible sera plutôt compliquée.

0
Stephen C

Je pense que le meilleur moyen est d'utiliser file.length == 0.

Il est parfois possible que la première ligne soit vide.

0
user3744089