我正在对IO进行一些研究,我阅读了以下有关缓冲技术的文章。为了最大限度地减少底层操作系统的磁盘访问和工作,缓冲技术使用一个临时缓冲区,以缓冲方式读取数据,而不是每次读取操作直接从磁盘读取数据。
没有和没有缓冲的例子。
没有缓冲:
try
{
File f = new File("Test.txt");
FileInputStream fis = new FileInputStream(f);
int b; int ctr = 0;
while((b = fis.read()) != -1)
{
if((char)b== '\t')
{
ctr++;
}
}
fs.close();
// not the ideal way
} catch(Exception e)
{}
缓冲:
try
{
File f = new File("Test.txt");
FileInputStream fis = new FileInputStream(f);
BufferedInputStream bs = new BufferedInputStream(fis);
int b;
int ctr = 0;
while((b =bs.read()) != -1)
{
if((char)b== '\t')
{
ctr++;
}
}
fs.close(); // not the ideal way
}
catch(Exception e){}
结论是:
Test.txt was a 3.5MB file
Scenario 1 executed between 5200 to 5950 milliseconds for 10 test runs
Scenario 2 executed between 40 to 62 milliseconds for 10 test runs.
在Java中有没有其他方法可以做得更好?或者任何其他方法/技术可以提供更好的性能?请指教..!
答案 0 :(得分:1)
您的代码的问题在于您正在逐字节地读取文件(每个请求一个字节)。通过chunk将其读入数组块 - 性能将等于Buffer的性能。
您可能还想尝试NIO和内存映射文件,请参阅http://www.linuxtopia.org/online_books/programming_books/thinking_in_java/TIJ314_029.htm
答案 1 :(得分:1)
在Java中有没有其他方法可以做得更好?或者提供更好性能的任何其他方法/技术?
就IO性能而言,如果没有其他很多代码,这可能是最好的。无论如何,你最有可能成为IO界限。
while((b = bs.read())!= -1)
逐字节读取效率非常低。如果您正在阅读文本文件,那么您应该使用BufferedReader
代替。这会将字节数组转换为String
。
BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
...
while ((String line = reader.readLine()) != null) {
...
}
此外,对于任何IO,您应该始终在try / finally块中执行此操作以确保关闭它:
FileInputStream fis = new FileInputStream(f);
BufferedReader reader;
try {
reader = new BufferedReader(new InputStreamReader(fis));
// once we wrap the fis in a reader, we just close the reader
} finally {
if (reader != null) {
reader.close();
}
if (fis != null) {
fis.close();
}
}
答案 2 :(得分:0)
您可以一次读取数据块,这仍然比使用缓冲输入更快。
FileInputStream fis = new FileInputStream(new File("Test.txt"));
int len, ctr = 0;
byte[] bytes = new byte[8192];
while ((len = fis.read(bytes)) > 0)
for (int i = 0; i < len; i++)
if (bytes[len] == '\t')
ctr++;
fis.close();
您也可以尝试内存映射。
FileChannel fc = new FileInputStream(new File("Test.txt")).getChannel();
ByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
int ctr = 0;
for (int i = 0; i < bb.limit(); i++)
if (bb.get(i) == '\t')
ctr++;
fc.close();
我希望这两个选项的速度都快两倍。