我需要在每个服务器启动时读取~50个文件,并将每个文本文件的表示放入内存中.每个文本文件都有自己的字符串(这是用于字符串持有者的最佳类型?).
将文件读入内存的最快方法是什么?保存文本的最佳数据结构/类型是什么,以便我可以在内存中操作它(主要是搜索和替换)?
谢谢
内存映射文件将是最快的...像这样:
final File file; final FileChannel channel; final MappedByteBuffer buffer; file = new File(fileName); fin = new FileInputStream(file); channel = fin.getChannel(); buffer = channel.map(MapMode.READ_ONLY, 0, file.length());
然后继续从字节缓冲区读取.
这将比FileInputStream
或快得多FileReader
.
编辑:
经过一番调查后发现,根据您的操作系统,您可能最好使用新的BufferedInputStream(new FileInputStream(file))
.然而,将所有内容一次性读入char []文件的大小听起来就像是最糟糕的方式.
因此,BufferedInputStream
应该在所有平台上提供大致一致的性能,而内存映射文件可能会缓慢或快速,具体取决于底层操作系统.与性能至关重要的一切一样,您应该测试代码并查看哪种方法最有效.
编辑:
好的,这里有一些测试(第一个测试完成两次以将文件放入磁盘缓存).
我在rt.jar类文件上运行它,解压缩到硬盘驱动器,这是在Windows 7 beta x64下.这是16784个文件,总共94,706,637个字节.
首先结果......
(记得第一次重复获取磁盘缓存设置)
ArrayTest中
时间= 83016
bytes = 118641472
ArrayTest中
时间= 46570
bytes = 118641472
DataInputByteAtATime
时间= 74735
bytes = 118641472
DataInputReadFully
时间= 8953
bytes = 118641472
存储器映射
时间= 2320
bytes = 118641472
这是代码......
import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.FileChannel.MapMode; import java.util.HashSet; import java.util.Set; public class Main { public static void main(final String[] argv) { ArrayTest.main(argv); ArrayTest.main(argv); DataInputByteAtATime.main(argv); DataInputReadFully.main(argv); MemoryMapped.main(argv); } } abstract class Test { public final void run(final File root) { final Setfiles; final long size; final long start; final long end; final long total; files = new HashSet (); getFiles(root, files); start = System.currentTimeMillis(); size = readFiles(files); end = System.currentTimeMillis(); total = end - start; System.out.println(getClass().getName()); System.out.println("time = " + total); System.out.println("bytes = " + size); } private void getFiles(final File dir, final Set files) { final File[] childeren; childeren = dir.listFiles(); for(final File child : childeren) { if(child.isFile()) { files.add(child); } else { getFiles(child, files); } } } private long readFiles(final Set files) { long size; size = 0; for(final File file : files) { size += readFile(file); } return (size); } protected abstract long readFile(File file); } class ArrayTest extends Test { public static void main(final String[] argv) { final Test test; test = new ArrayTest(); test.run(new File(argv[0])); } protected long readFile(final File file) { InputStream stream; stream = null; try { final byte[] data; int soFar; int sum; stream = new BufferedInputStream(new FileInputStream(file)); data = new byte[(int)file.length()]; soFar = 0; do { soFar += stream.read(data, soFar, data.length - soFar); } while(soFar != data.length); sum = 0; for(final byte b : data) { sum += b; } return (sum); } catch(final IOException ex) { ex.printStackTrace(); } finally { if(stream != null) { try { stream.close(); } catch(final IOException ex) { ex.printStackTrace(); } } } return (0); } } class DataInputByteAtATime extends Test { public static void main(final String[] argv) { final Test test; test = new DataInputByteAtATime(); test.run(new File(argv[0])); } protected long readFile(final File file) { DataInputStream stream; stream = null; try { final int fileSize; int sum; stream = new DataInputStream(new BufferedInputStream(new FileInputStream(file))); fileSize = (int)file.length(); sum = 0; for(int i = 0; i < fileSize; i++) { sum += stream.readByte(); } return (sum); } catch(final IOException ex) { ex.printStackTrace(); } finally { if(stream != null) { try { stream.close(); } catch(final IOException ex) { ex.printStackTrace(); } } } return (0); } } class DataInputReadFully extends Test { public static void main(final String[] argv) { final Test test; test = new DataInputReadFully(); test.run(new File(argv[0])); } protected long readFile(final File file) { DataInputStream stream; stream = null; try { final byte[] data; int sum; stream = new DataInputStream(new BufferedInputStream(new FileInputStream(file))); data = new byte[(int)file.length()]; stream.readFully(data); sum = 0; for(final byte b : data) { sum += b; } return (sum); } catch(final IOException ex) { ex.printStackTrace(); } finally { if(stream != null) { try { stream.close(); } catch(final IOException ex) { ex.printStackTrace(); } } } return (0); } } class DataInputReadInChunks extends Test { public static void main(final String[] argv) { final Test test; test = new DataInputReadInChunks(); test.run(new File(argv[0])); } protected long readFile(final File file) { DataInputStream stream; stream = null; try { final byte[] data; int size; final int fileSize; int sum; stream = new DataInputStream(new BufferedInputStream(new FileInputStream(file))); fileSize = (int)file.length(); data = new byte[512]; size = 0; sum = 0; do { size += stream.read(data); sum = 0; for(int i = 0; i < size; i++) { sum += data[i]; } } while(size != fileSize); return (sum); } catch(final IOException ex) { ex.printStackTrace(); } finally { if(stream != null) { try { stream.close(); } catch(final IOException ex) { ex.printStackTrace(); } } } return (0); } } class MemoryMapped extends Test { public static void main(final String[] argv) { final Test test; test = new MemoryMapped(); test.run(new File(argv[0])); } protected long readFile(final File file) { FileInputStream stream; stream = null; try { final FileChannel channel; final MappedByteBuffer buffer; final int fileSize; int sum; stream = new FileInputStream(file); channel = stream.getChannel(); buffer = channel.map(MapMode.READ_ONLY, 0, file.length()); fileSize = (int)file.length(); sum = 0; for(int i = 0; i < fileSize; i++) { sum += buffer.get(); } return (sum); } catch(final IOException ex) { ex.printStackTrace(); } finally { if(stream != null) { try { stream.close(); } catch(final IOException ex) { ex.printStackTrace(); } } } return (0); } }