簡體   English   中英

在Windows上檢查Java中文件是否為空的最有效方法

[英]Most efficient way to check if a file is empty in Java on Windows

我試圖在Windows上用Java檢查日志文件是否為空(意味着沒有錯誤)。 到目前為止,我嘗試過使用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 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
}

它有什么問題嗎?

這是對Saik0的答案的改進,該答案基於Anwar Shaikh的評論,即太大的文件(高於可用內存)將引發異常:

使用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方法,但現在可能還沒有時間放棄。 如果BOM字段正在銷毀,請嘗試在stackoverflow上發布此解決方案。

字節順序標記用Java解壓縮文件讀取

另一種方法是(使用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的類。

現在,當日志文件為空(沒有內容)時,這些方法都會失敗,但文件大小不為零(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()和/或只讀取前兩個字節來Files.length() 但問題包括:

  • 如果你們都測試文件大小並讀取前幾個字節,那么你正在進行2次系統調用。
  • 實際的線路終止序列可以是CR,NL或CR NL,具體取決於平台。 (我知道你說這是針對Windows的,但是如果你需要移植你的應用程序會怎么樣?或者如果有人發給你一個非Windows文件?)
  • 避免設置流/讀取器堆棧會很好,但文件的字符編碼可以將CR和NL映射到字節0x0d0x0a之外的其他內容。 (例如...... UTF-16)
  • 然后有一些令人討厭的習慣,一些Windows實用程序已將BOM標記放入UTF-8編碼文件中。 (這甚至會弄亂上面的簡單版本!)

所有這些意味着最有效的解決方案將變得相當復雜。

我認為最好的方法是使用file.length == 0

有時可能第一行是空的。

我結合了兩個最佳解決方案來涵蓋所有可能性:

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

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 :文件是否至少有一個字節:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM