问题标签 [mappedbytebuffer]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
333 浏览

java - 使用 MappedByteBuffer 进行快速非阻塞读/写?

我正在将来自供应商的消息作为数据流处理,并希望将 msgSeqNum 本地存储在本地文件中。原因:

他们发送 msgSeqNum 来唯一标识每条消息。它们提供“同步和流”功能,以便在从给定序列号重新连接时流式传输消息。假设如果 msgSeqNum 从 1 开始并且我的连接在 msgSeqNum 50 时断开并错过了接下来的 100 条消息(供应商服务器的当前 msgSeqNum 现在是 150),那么当我重新连接到供应商时,我需要调用“同步和流”使用 msgSeqNum=50 获取错过的 100 条消息。

所以我想了解如何在本地保存 msgSeqNum 以便快速访问。我假设

1)由于读/写频繁发生,即在处理每条消息时(读取忽略重复,在处理完消息后写入更新msgSeqNum),我认为最好使用Java NIO的'MappedByteBuffer'?

2)有人可以确认下面的代码是否最适合我公开映射的字节缓冲区对象以用于读取和写入,并在进程的生命周期内保持 FileChannel 处于打开状态?下面的示例 Junit 代码:

我知道这可以通过一般的 Java 文件操作来读取和写入文件来实现,但我需要一些快速的东西,这相当于非 IO,因为我使用的是单个写入器模式,并且希望快速处理这些消息。 -阻塞方式。

0 投票
0 回答
215 浏览

java - 如何使用 MappedByteBuffer 读取大文件?

我想使用MappedByteBuffer.

问题:

我能在这里做什么?

0 投票
0 回答
32 浏览

java - 通过 MappedByteBuffer 写入临时文件后无法删除它

当我运行这个 JUnit 测试时,它失败了,因为file.delete()返回false

为什么会这样?我认为在 try 块之后所有资源都已关闭,应该没有file.delete()失败的原因。

0 投票
1 回答
233 浏览

java - 如何防止 MappedByteBuffer 在文件末尾写入空字符?

作为分配的一部分,我正在使用具有固定缓冲区大小的 Java 的 MappedByteBuffer 写入文件。它应该逐个字符地写入,因为缓冲区大小可以小于行长。但问题是它将文件末尾缓冲区的剩余位置写为空字符。如何删除那些空字符?

这是一个示例代码:

这是输出(使用 Sublime Text utf-8 编码打开):

0 投票
1 回答
370 浏览

java - MappedByteBuffer(在 Android Studio 中)构造函数损坏(超级构造函数损坏)

我有一个字节数组,它必须转换为 MappedByteBuffer。

但是当我尝试创建 MappedByteBuffer 时,会发生错误。

error: cannot find symbol method MappedByteBuffer(int,int,int,int,byte[],int)

MappedByteBuffer.java

字节缓冲区.java

我觉得奇怪的是当extends ByteBuffer在 MappedByteBuffer.java 中定义 goto 时,它显示的是 ByteBuffer.annotated.java,而不是 ByteBuffer.java

ByteBuffer.annotated.java

我不知道 {classname}.annotated.java 做了什么,所以它可能不是错误,但我粘贴了,因为我认为它很奇怪。

那么如何从字节数组创建 MappedByteBuffer 呢?只有 1 个构造函数,但它已损坏。

0 投票
3 回答
3567 浏览

java - 将文件用于共享内存 IPC

在我的应用程序中,有一个进程将数据写入文件,然后响应接收请求,将通过网络将(部分)数据发送到请求进程。这个问题的基础是看当两个进程碰巧在同一个主机上时,我们是否可以加快通信速度。(在我的例子中,流程是 Java,但我认为这个讨论可以更广泛地应用。)

有一些项目使用 Java 的 FileChannel.map() 返回的 MappedByteBuffers 作为在同一主机上的 JVM 之间共享内存 IPC 的一种方式(请参阅 Chronicle Queue、Aeron IPC 等)。

加速同一主机通信的一种方法是让我的应用程序使用其中一种技术来为同一主机通信提供请求-响应路径,或者结合现有的写入数据文件的机制,或者通过提供通信和写入文件的统一方式。

另一种方法是允许请求进程直接访问数据文件。

我倾向于支持第二种方法——假设它是正确的——因为它更容易实现,并且似乎比为每个请求复制/传输数据副本更有效(假设我们没有替换现有的写入机制到文件)。

本质上,我想了解当两个进程可以访问同一个文件并使用它进行通信时究竟会发生什么,特别是 Java (1.8) 和 Linux (3.10)。

据我了解,如果两个进程同时打开同一个文件,它们之间的“通信”基本上将通过“共享内存”。

请注意,此问题与是否使用 MappedByteBuffer 的性能影响无关 - 与读取和写入文件相比,使用映射缓冲区以及减少复制和系统调用似乎很有可能会减少开销,但是可能需要对应用程序进行重大更改。

以下是我的理解:

  1. 当 Linux 从磁盘加载文件时,它会将该文件的内容复制到内存中的页面。该内存区域称为页面缓存。据我所知,无论使用哪种 Java 方法(FileInputStream.read()、RandomAccessFile.read()、FileChannel.read()、FileChannel.map())或本机方法来读取文件,它都会执行此操作(观察“免费”并监控“缓存”值)。
  2. 如果另一个进程尝试加载相同的文件(当它仍然驻留在缓存中时),内核会检测到这一点并且不需要重新加载文件。如果页面缓存已满,页面将被逐出——脏页面被写回磁盘。(如果有明确的磁盘刷新,页面也会被写回,并且定期使用内核线程)。
  3. 缓存中已经有一个(大)文件可以显着提高性能,这比基于我们使用哪些 Java 方法打开/读取该文件的差异要大得多。
  4. 如果使用 mmap 系统调用 (C) 或通过 FileChannel.map() (Java) 加载文件,则基本上文件的页面(在缓存中)被直接加载到进程的地址空间中。使用其他方法打开文件,将文件加载到不在进程地址空间中的页面中,然后读取/写入该文件的各种方法将一些字节从/到这些页面复制到进程地址空间中的缓冲区中. 避免该副本有明显的性能优势,但我的问题与性能无关。

所以总而言之,如果我理解正确的话——虽然映射提供了性能优势,但它似乎并没有提供任何我们还没有从 Linux 和页面缓存的性质中获得的“共享内存”功能。

所以,请让我知道我的理解在哪里。

谢谢。

0 投票
0 回答
41 浏览

java - 将包含浮点值的大型 CSV 或 Excel 文件传递​​给 Java MappedByteBuffer,而不必逐行或逐行分隔值

我正在尝试将带有浮点值的大型 CSV 传递给 MappedByteBuffer。我希望它被读取为浮点值而不是文本,并且不希望必须逐个字符地解析它并删除逗号(分隔符)。我想在不使用任何内存的情况下将其处理为二维数组(由索引管理),即不将其放入任何变量中进行遍历等。我正在使用的代码是:-

我也尝试过使用 floatBuffer 但它也不起作用。我知道它是一个文本文件,其值用逗号分隔,我愿意改用 excel 文件。但问题是如何使用浮点数据,而不必在将其放入映射字节缓冲区之前或之后将所有内容放入内存中,这是我们实际上试图通过使用内存映射数据结构来避免的)。

编辑:我所做的是解析 CSV 并将其写入浮点数的二进制 (.bin) 文件,然后在实际程序中通过 MappedByteBuffer (asFloatBuffer) 直接从该 (.bin) 文件中读取数据。这消除了执行期间的字符串解析和浮点转换。

0 投票
1 回答
49 浏览

java - Java mmap MappedByteBuffer

假设我已经映射了一个内存区域 [0, 1000],现在我有了 MappedByteBuffer。

假设每个线程为 exp 访问缓冲区的不同部分,我是否可以同时从多个线程读取和写入此缓冲区而无需锁定。T1 [0, 500), T2 [500, 1000]?

如果上述情况属实,是否可以确定是为多个线程创建一个大缓冲区,还是为每个线程创建一个较小的缓冲区?