- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想以非常快的方式读取一个大文件。我正在使用MappedByteBuffer
,如下所示:
String line = "";
try (RandomAccessFile file2 = new RandomAccessFile(new File(filename), "r"))
{
FileChannel fileChannel = file2.getChannel();
MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size());
for (int i = 0; i < buffer.limit(); i++)
{
char a = (char) buffer.get();
if (a == '\n'){
System.out.println(line);
line = "";
}else{
line += Character.toString(c);
}
}
这无法正常工作。它正在更改文件的内容并打印更改的内容。有没有更好的方法使用 MappedByteBuffer 读取文件的一行?
最终我想分割该行并提取某些内容(因为它的 csv),所以这只是重现问题的最小示例。
最佳答案
我使用一个充满随机字符串的 21 GB 文件进行了一些测试,每行长度为 20-40 个字符。看来内置的 BufferedReader 仍然是最快的方法。
File f = new File("sfs");
try(Stream<String> lines = Files.lines(f.toPath(), StandardCharsets.UTF_8)){
lines.forEach(line -> System.out.println(line));
} catch (IOException e) {}
将行读取到流中可确保您根据需要读取行,而不是立即读取整个文件。
要进一步提高速度,您可以适度增加 BufferedReader 的缓冲区大小。在我的测试中,它在大约 1000 万行时开始优于正常缓冲区大小。
CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
int size = 8192 * 16;
try (BufferedReader br = new BufferedReader(new InputStreamReader(newInputStream(f.toPath()), decoder), size)) {
br.lines().limit(LINES_TO_READ).forEach(s -> {
});
} catch (IOException e) {
e.printStackTrace();
}
我用于测试的代码:
private static long LINES_TO_READ = 10_000_000;
private static void java8Stream(File f) {
long startTime = System.nanoTime();
try (Stream<String> lines = Files.lines(f.toPath(), StandardCharsets.UTF_8).limit(LINES_TO_READ)) {
lines.forEach(line -> {
});
} catch (IOException e) {
e.printStackTrace();
}
long endTime = System.nanoTime();
System.out.println("no buffer took " + (endTime - startTime) + " nanoseconds");
}
private static void streamWithLargeBuffer(File f) {
long startTime = System.nanoTime();
CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
int size = 8192 * 16;
try (BufferedReader br = new BufferedReader(new InputStreamReader(newInputStream(f.toPath()), decoder), size)) {
br.lines().limit(LINES_TO_READ).forEach(s -> {
});
} catch (IOException e) {
e.printStackTrace();
}
long endTime = System.nanoTime();
System.out.println("using large buffer took " + (endTime - startTime) + " nanoseconds");
}
private static void memoryMappedFile(File f) {
CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
long linesReadCount = 0;
String line = "";
long startTime = System.nanoTime();
try (RandomAccessFile file2 = new RandomAccessFile(f, "r")) {
FileChannel fileChannel = file2.getChannel();
MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0L, Integer.MAX_VALUE - 10_000_000);
CharBuffer decodedBuffer = decoder.decode(buffer);
for (int i = 0; i < decodedBuffer.limit(); i++) {
char a = decodedBuffer.get();
if (a == '\n') {
line = "";
} else {
line += Character.toString(a);
}
if (linesReadCount++ >= LINES_TO_READ){
break;
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
long endTime = System.nanoTime();
System.out.println("using memory mapped files took " + (endTime - startTime) + " nanoseconds");
}
顺便说一句,我注意到 FileChannel.map throws an exception如果映射文件大于 Integer.MAX_VALUE,这使得该方法对于读取非常大的文件不切实际。
关于java - 如何使用MappedByteBuffer从java中的映射文件中逐行读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56393358/
我有一个 java.nio.MappedByteBuffer,用于从小端文件中读取整数。我使用 ByteBuffer.order() 将字节顺序设置为 LITTLE_ENDIAN,但这会导致缓冲区将整
我很难理解 MappedByteBuffer 的读写。这是我的类,它读取本地文件的内容并假设反转其内容。我使用的是 java 版本 8。 public class MappedByteBufferEx
据我所知,在调用 FileChannel.map 之后,MappedByteBuffer 将文件内容“映射”到内存中,但不一定将整个文件加载到内存中. 所以,如果我开始阅读,例如在 pos(0) 处,
长期读者,第一次发帖。 我在从一组二进制文件快速读取数据时遇到了一些问题。 ByteBuffers 和 MappedBytBuffers 提供了我需要的性能,但它们似乎需要初始运行来预热。我不确定这是
我将文件读入MappedByteBuffer: MappedByteBuffer buffer = FileChannel.open(file, StandardOpenOption.READ)
我可以让 2 个 Java 进程通过 MappedByteBuffer 共享一个内存区域。 但是,如果这两个进程可以同时读取或写入偏移量x(从共享内存开始处)的字节,我如何同步对该字节的访问? 这是所
我想读取一个 150 MB 的文本文件并将文件的内容拆分为单词。当我使用 MappedByteBuffer 执行此操作时,文件大小为 135 mb 需要 12 秒。当我对 BufferedReader
我有一个程序在重新启动之前运行了 12 个多小时。该程序是一个 minecraft 服务器,因此它不能经常重新启动。 无论如何,大约每 25-35 分钟就会读取一个大小为 42-67mb 的文件。我使
我有一个 MappedByteBuffer,其中一部分包含 PNG 文件的字节。 我想调用:BitmapFactory.decodeByteArray(byte[] data, int offset,
设置和问题 我正在将一个文件转换为一个新文件,但不知道输出缓冲区应该有多大 加密、编码、压缩等都具有这个特性 如果输出MappedByteBuffer太小,将会抛出java.nio.BufferOve
我对 MappedByteBuffer 有一个问题,特别是它的内部工作方式。据我了解,缓存完全由操作系统完成。因此,如果我从文件中读取(使用 MappedByteBuffer),操作系统将从硬盘驱动器
有什么方法可以让 MappedByteBuffer 在文件上有一个滑动窗口。我有一个非常大的文件 (20GB),但我一次只想制作 100MB。我试过这只是丢弃旧缓冲区并从 channel 创建一个新缓
在我看来MappedByteBuffer.isLoaded()在 Windows 上始终返回 false。当我在 BSD Unix 上测试时,我使用相同的测试数据得到 true。 我应该担心吗?无论我
这是我正在运行的代码: import java.io.RandomAccessFile; import java.nio.MappedByteBuffer; import java.nio.chann
我有一个应用程序,其中发生大量文件 I/O(读取和写入)。我知道使用多个线程执行文件 I/O 并不是一个好的解决方案,因为它会降低性能(我无法控制所使用的磁盘类型)。因此,我最终将一个线程专门用于所有
我有一个小而简单的存储系统,可以通过内存映射文件访问。因为我需要处理超过 2GB 的空间,所以我需要一个固定大小的 MappedByteBuffer 列表,例如 2GB(由于不同的原因,我使用的较少)
我有几个 100k 值的大型 double 组和长数组,每个数组都需要在给定时间访问以进行计算,即使请求了 largeHeap,Android 操作系统也没有给我足够的内存,而且我在大多数测试设备中不
关于Expanding Java Memory-Mapped Byte Buffer ,为什么缓冲区在写入超过限制时不扩展?甚至没有一种方法可以在不重新映射缓冲区的情况下实现该行为。这对我来说也有点奇
我真的遇到了麻烦:我想使用 FileChannel 和 MappedByteBuffer 读取超过几个 GB 的巨大文件 - 我发现的所有文档都表明映射相当简单使用 FileChannel.map()
我遇到了一个问题,我创建了大小为 1KB 的 MappedByteBuffer,并滑动了大小为 20MB 的文件。 for(20MB file) { writeBuffer = fc.map(
我是一名优秀的程序员,十分优秀!