Самый эффективный способ проверить, является ли файл пустым в Java на Windows - PullRequest
24 голосов
/ 25 августа 2011

Я пытаюсь проверить, является ли файл журнала пустым (то есть без ошибок) или нет, в 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 байта).

Что является наиболее эффективным и точный способ проверить, пуст ли файл?Я попросил об эффективности, так как мне нужно постоянно проверять размер файла в цикле.

Примечание: Размер файла колеблется от нескольких до 10 КБ!

Метод 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!");

Ответы [ 11 ]

41 голосов
/ 25 августа 2011

Проверьте, пуста ли первая строка файла:

BufferedReader br = new BufferedReader(new FileReader("path_to_some_file"));     
if (br.readLine() == null) {
    System.out.println("No errors, and file empty");
}
18 голосов
/ 14 июня 2012

Почему бы просто не использовать:

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

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

Что-то не так?

2 голосов
/ 29 января 2016

Это улучшение ответа 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 голосов
/ 25 августа 2011

Вы можете попробовать воспользоваться подходом FileReader, но сейчас еще не время сдаваться.Если поле спецификации разрушает для вас, попробуйте это решение, размещенное здесь в stackoverflow.

Порядок следования байтов портит чтение файлов в Java

1 голос
/ 27 декабря 2017
String line = br.readLine();
String[] splitted = line.split("anySplitCharacter");
if(splitted.length == 0)
    //file is empty
else
    //file is not empty

У меня была такая же проблема с моим текстовым файлом.Хотя он был пустым, значение, возвращаемое методом readLine, не было нулевым.Поэтому я попытался присвоить его значение массиву String, который я использовал для доступа к разделенным атрибутам моих данных.Это сработало для меня.Попробуйте и скажите мне, работает ли это и на вас.

1 голос
/ 30 октября 2014

Еще один способ сделать это (используя 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());
    }        
}
1 голос
/ 25 августа 2011

Попробуйте FileReader, этот ридер предназначен для чтения потока символов, а FileInputStream - для чтения необработанных данных.

Из Javadoc:

FileReader предназначен для чтения потоков символов. Для чтения потоки необработанных байтов, рассмотрите возможность использования FileInputStream.

Поскольку вы хотите прочитать файл журнала, FileReader - это класс для использования IMO.

0 голосов
/ 28 июля 2017

Я думаю, что лучше всего использовать file.length == 0.

Иногда возможно, что первая строка пуста.

0 голосов
/ 28 апреля 2016

Теперь оба эти метода иногда терпят неудачу, когда файл журнала пуст (не имеет содержимого), но размер файла не равен нулю (2 байта).

На самом деле, я думаю, вы обнаружите, что файл НЕ пуст. Скорее, я думаю, что вы обнаружите, что эти два символа - CR и NL; файл состоит из одной пустой строки.

Если вы хотите проверить, является ли файл пустым или имеет одну пустую строку, тогда простой, относительно эффективный способ:

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

Можем ли мы сделать это более эффективно? Возможно. Это зависит от того, как часто вам приходится иметь дело с тремя разными случаями:

  • совершенно пустой файл
  • файл, состоящий из одной пустой строки
  • файл с непустой строкой или несколькими строками.

Вероятно, вы можете добиться большего успеха, используя Files.length() и / или читая только первые два байта. Тем не менее, проблемы включают в себя:

  • Если вы оба проверили размер файла И прочитали первые несколько байтов, вы делаете 2 системных вызова.
  • Фактическая последовательность завершения строки может быть CR, NL или CR NL, в зависимости от платформы. (Я знаю, вы говорите, что это для Windows, но что произойдет, если вам нужно портировать ваше приложение? Или если кто-то отправит вам файл не из Windows?)
  • Было бы неплохо избежать настройки стека потоков / считывателей, но кодировка символов файла может отображать CR и NL во что-то, отличное от байтов 0x0d и 0x0a. (Например ... UTF-16)
  • Кроме того, некоторые утилиты Windows раздражают, что маркеры спецификации помещаются в файлы в кодировке UTF-8. (Это даже испортило бы простую версию выше!)

Все это означает, что наиболее эффективное из возможных решений будет довольно сложным.

0 голосов
/ 25 августа 2011

Идея вашего первого фрагмента верна. Вы, вероятно, хотели проверить iByteCount == -1: есть ли в файле хотя бы один байт:

if (iByteCount == -1)  
    System.out.println("NO ERRORS!");
else
    System.out.println("SOME ERRORS!");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...