有效读取 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
以获得最高效率。
我正在研究霍夫曼编码的简单实现,它适用于使用某种形式的文本编码的任何文件,但当我尝试以任何其他格式(例如 .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
以获得最高效率。