我正在尝试多种方法将文件的字节解码为字符。
使用 java.io.Reader 和 Channels.newReader(...)
public static void decodeWithReader() throws Exception {
FileInputStream fis = new FileInputStream(FILE);
FileChannel channel = fis.getChannel();
CharsetDecoder decoder = Charset.defaultCharset().newDecoder();
Reader reader = Channels.newReader(channel, decoder, -1);
final char[] buffer = new char[4096];
for(;;) {
if(-1 == reader.read(buffer)) {
break;
}
}
fis.close();
}
手动使用缓冲区和解码器:
public static void readWithBuffers() throws Exception {
FileInputStream fis = new FileInputStream(FILE);
FileChannel channel = fis.getChannel();
CharsetDecoder decoder = Charset.defaultCharset().newDecoder();
final long fileLength = channel.size();
long position = 0;
final int bufferSize = 1024 * 1024; // 1MB
CharBuffer cbuf = CharBuffer.allocate(4096);
while(position < fileLength) {
MappedByteBuffer bbuf = channel.map(MapMode.READ_ONLY, position, Math.min(bufferSize, fileLength - position));
for(;;) {
CoderResult res = decoder.decode(bbuf, cbuf, false);
if(CoderResult.OVERFLOW == res) {
cbuf.clear();
} else if (CoderResult.UNDERFLOW == res) {
break;
}
}
position += bbuf.position();
}
fis.close();
}
对于 200MB 的文本文件,第一种方法始终需要 300 毫秒才能完成。第二种方法始终需要 700 毫秒。您知道为什么阅读器方法要快得多吗?
它能否通过其他实现运行得更快?
基准测试在 Windows 7 和 JDK7_07 上执行。
最佳答案
为了比较,你可以试试。
public static void readWithBuffersISO_8859_1() throws Exception {
FileInputStream fis = new FileInputStream(FILE);
FileChannel channel = fis.getChannel();
MappedByteBuffer bbuf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
while(bbuf.remaining()>0) {
char ch = (char)(bbuf.get() & 0xFF);
}
fis.close();
}
这假定了 ISO-8859-1。如果您想要最快的速度,将文本视为二进制格式会有所帮助(如果可以的话)。
正如@EJP 指出的那样,您一次性更改了很多东西,您需要从最简单的可比较示例开始,看看每个元素增加了多少差异。
关于java - 在 Java 中解码字符 : why is it faster with a reader than using buffers?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13120585/