Java.io:性能调优
我有一个约4MB的文件,该文件是一个ascii文件,仅包含普通键盘字符。我在java.io包中尝试了许多类,以字符串形式读取文件内容。逐个字符读取它们(使用FileReader和BufferedReader)需要 大约40秒,使用java.nio包(FileChannel和ByteBuffer)读取内容大约需要25秒。这是从我的知识更大一点 时间量。有人知道如何将这段时间的消耗减少到一定程度吗 大约10秒?甚至像使用C创建文件读取器和从java调用这样的解决方案也可以。我使用下面的代码片段在22秒内读取了4MB的文件-Java.io:性能调优,java,file-io,io,nio,filereader,Java,File Io,Io,Nio,Filereader,我有一个约4MB的文件,该文件是一个ascii文件,仅包含普通键盘字符。我在java.io包中尝试了许多类,以字符串形式读取文件内容。逐个字符读取它们(使用FileReader和BufferedReader)需要 大约40秒,使用java.nio包(FileChannel和ByteBuffer)读取内容大约需要25秒。这是从我的知识更大一点 时间量。有人知道如何将这段时间的消耗减少到一定程度吗 大约10秒?甚至像使用C创建文件读取器和从java调用这样的解决方案也可以。我使用下面的代码片段在22
public static String getContents(File file) {
try {
if (!file.exists() && !file.isFile()) {
return null;
}
FileInputStream in = new FileInputStream(file);
FileChannel ch = in.getChannel();
ByteBuffer buf = ByteBuffer.allocateDirect(512);
Charset cs = Charset.forName("ASCII");
StringBuilder sb = new StringBuilder();
int rd;
while ((rd = ch.read(buf)) != -1) {
buf.rewind();
CharBuffer chbuf = cs.decode(buf);
for (int i = 0; i < chbuf.length(); i++) {
sb.append(chbuf.get());
}
buf.clear();
}
String contents = sb.toString();
System.out.println("File Contents:\n"+contents);
return contents;
} catch (Exception exception) {
System.out.println("Error:\n" + exception.getMessage());
return null;
}
}
公共静态字符串getContents(文件){
试一试{
如果(!file.exists()&&!file.isFile()){
返回null;
}
FileInputStream in=新的FileInputStream(文件);
FileChannel ch=in.getChannel();
ByteBuffer buf=ByteBuffer.allocateDirect(512);
Charset cs=Charset.forName(“ASCII”);
StringBuilder sb=新的StringBuilder();
国际公路;
而((rd=ch.read(buf))!=-1){
buf.倒带();
CharBuffer chbuf=cs.decode(buf);
对于(int i=0;i
我无法想象您的硬件可能是什么,但对于一个4 MB的文件,它应该需要不到0.1秒的时间
一次读取所有文件的快速方法是将其读入一个字节[]
public static String readFileAsString(File file) {
try {
DataInputStream in = new DataInputStream(FileInputStream(file));
byte[] bytes = new byte[(int) file.length()];
in.readFully(bytes);
in.close();
return new String(bytes, 0); // ASCII text only.
} catch (FileNotFoundException e) {
return null;
} catch (IOException e) {
System.out.println("Error:\n" + e.getMessage());
return null;
}
}
public static void main(String... args) throws IOException {
File tmp = File.createTempFile("deleteme", "txt");
tmp.deleteOnExit();
byte[] bytes = new byte[4 * 1024 * 1024];
Arrays.fill(bytes, (byte) 'a');
FileOutputStream fos = new FileOutputStream(tmp);
fos.write(bytes);
fos.close();
long start = System.nanoTime();
String s = readFileAsString(tmp);
long time = System.nanoTime() - start;
System.out.printf("Took %.3f seconds to read a file with %,d bytes%n",
time / 1e9, s.length());
}
印刷品
Took 0.026 seconds to read a file with 4,194,304 bytes
如果您想更快地读取该文件,我建议使用内存映射文件,因为它将花费不到10毫秒的时间,但在这种情况下,这是一种过度的杀伤力。您可以增加缓冲区大小,比如说2048或4096字节 不要使用本机API,因为您不会获得编译时类型检查之类的Java特性
你为什么一个字节一个字节地读?您知道文件的大小-分配一个足够大的字节数组来保存文件内容,并使用read()完全读取。是的,您是对的,读取5 MB的文件(088毫秒)所需的时间非常少。但在控制台(System.out)上显示需要很长时间(40秒)。原因是什么?有人能解释一下吗?我原以为这40秒是用来阅读的,但实际上控制台更新屏幕的速度很慢。如果您使用的是MS-DOS控制台,那么它会非常慢。如果您想知道为什么MS-DOS控制台会慢,那是因为它自创建以来没有太大变化。系统输出速度非常慢。它正在假脱机到操作系统控制台。长时间explanation@mcfinnigan当重定向到文件时,System.out不慢。尝试
javamyclass>output.txt
,您会发现它的速度非常快。