有效读取 java 中的任何文件作为字符串

read any file efficiently in java as string

我正在研究霍夫曼编码的简单实现,它适用于使用某种形式的文本编码的任何文件,但当我尝试以任何其他格式(例如 .mp4 .png .exe)读取时,它仍然工作但变得非常慢 (对于相同大小的文件,分钟而不是不到一秒)。

我的问题是我应该使用另一种方法来读取这些文件,以便读取速度取决于文件的大小而不是它的格式,如果是的话,它是什么?谢谢。

这是我的 IO class 它使用包装在 bufferedReader 中的 fileReader 根据在控制台中输入的路径读取文件。

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class IO {
    public String readFile(String path, boolean includeNewLine) {
        String returnString = "";
        try {
            FileReader fileReader = new FileReader(path);

            BufferedReader bufferedReader = new BufferedReader(fileReader);

            String line;
            int nLines = 0;
            while((line = bufferedReader.readLine()) != null) {
                if(nLines > 0 && includeNewLine) {
                    returnString += "\n";
                }
                returnString += line;
                nLines++;
            }   

            bufferedReader.close();         
        } catch(FileNotFoundException e) {
            System.out.println("Unable to open file '" + path + "'");                
        } catch(IOException e) {
            System.out.println("Error reading file '" + path + "'");                  
        }

        return returnString;
    }
}

returnString 中,您通过将新行附加到上一行来创建 String 的新实例。相反,我建议您使用 StringBuilder 如下:

StringBuilder fileContent = new StringBuilder();
//do your stuff
fileContent.append(line);

通过这种方式,您可以继续重复使用同一个构建器对象。此外,如果您正在阅读二进制内容,那么最好使用 InputStream 层次结构中的 class。

我们确实有来自 nio 包的 Files class,您可以使用它来获取如下行:

try (Stream<String> stream = Files.lines( Paths.get(filePath), StandardCharsets.UTF_8)) {
    stream.forEach(s -> fileContent.append(s).append("\n"));
}

另一种方法是使用 Apache commons IO 提供的已经测试过的代码 api FileUtils.readFileToString

也许这会有所帮助:FileInputStream 与 FileReader

当然,将您的方法更改为使用 StringBuilder(但这是另一个问题)。

只要您试图将文件解释为 String,您就会 运行 遇到效率问题。任何二进制格式都可能产生 巨大的 字符串,甚至超过字符串可以容纳的最大 64K,因为可能永远不会有一个字节被您解释为行尾字符 ('\n').

您应该将文件解释为字节序列。使用内存映射 ByteBuffer 以获得最高效率。