在Java中读取C++的内存映射文件

18

我有一个使用C++编写的程序,在其中的某一点使用了

hMapFile = OpenFileMapping(dwDesiredAccess, bInheritHandle, lpName);

lpName是类似于没有扩展名或路径的"myfile",即内存映射文件。我可以使用WinObj-Browser(WinObj)在路径Sessions\1\BaseNamedObjects\myfile中找到该文件。如果我尝试在Java中读取该特定文件,我尝试了:

File file = new File("myfile");
FileChannel filechannel = new RandomAccessFile(file, "r").getChannel();
MappedByteBuffer buffer = filechannel.map(FileChannel.MapMode.READ_ONLY, 0, filechannel.size());

但我总是遇到同样的错误:找不到指定的文件RandomAccessFile命令中。也许需要另一个文件访问?哪一个?

根据其他文章的理解,他们总是使用路径和扩展名,然而,在我的情况下,我不知道路径和扩展名会是什么...

我正在寻找一种访问内核对象命名空间的方法。

我知道有这个JNI例子(使用JNI进行内存映射),但是我想保持简单,并使用nio(如果可能的话)。

更新

因此,我刚在C#中尝试了整件事情,它非常容易,只用了不到5行代码。


1
C++程序的当前工作目录是什么?这就是文件创建的位置。如果您没有指定绝对路径,那么文件名将在进程当前工作目录的相对路径中创建。如果C++和Java程序的两个工作目录不同,则无法使用相对路径,您应该指定一个在两个程序中都相同的绝对路径来查找文件。 - Some programmer dude
@ErwinBolwidt:是的,它确实存在。我在问题中写道,在winobj浏览器中测试Java应用程序时,我可以访问该文件。 @JoachimPileborg:它类似于C:\ Project \ server \,愚蠢的问题:该文件在“资源管理器”中不可见,但我猜它不应该出现? - rst
1
文件映射对象不是文件系统的一部分。工作目录并不相关。您还需要调用 OpenFileMappingRandomAccessFile 不会这样做。 - David Heffernan
据我所知,在 Java 中不存在 OpenFileMapping,那么相应的等效方法是什么?@DavidHeffernan - rst
1
我不知道Java库是否支持打开命名映射。MappedByteBuffer似乎要求您手头有文件系统文件名。我倾向于使用JNI或JNA。 - David Heffernan
2个回答

1
一个文件就是一个文件,我同意"Joachim Pileborg"的观点,Java程序没有在其工作目录中找到该文件。请尝试。
String working dir = System.getProperty("user.dir");

并确保文件在正确的路径中。

嗨,那样行不通,请查看 https://msdn.microsoft.com/en-us/library/dd997372%28v=vs.110%29.aspx 中的“非持久化内存映射文件”。我在谈论用于IPC的共享内存。 - rst

0

你需要使用CreateFileMapping而不是OpenFileMapping。这样,你将在磁盘上创建一个与文件映射相关联的实际文件。

注意:重要的是要注意,使用常规的读/写方法将不会与不同进程的文件映射同步。因此,你仍然需要像Java中的MappedByteBuffer一样使用某些东西。


@DavidHeffernan: 是的,我也明白了。CreateFileMapping将创建一个基于真实文件的新文件映射,或者打开现有的文件映射(而OpenFileMapping将打开一个现有的映射,或者创建一个不基于任何真实文件的新文件映射)。 - Daniel
获取文件句柄就像使用特定文件名的CreateFile一样困难。每个进程可以使用不同的句柄(指向同一文件)。并且,使用文件名可以创建一个MappedByteBuffer对象... - Daniel
用户为什么会知道特定的文件名呢?我想象用户只有文件映射对象的名称。而且这并不需要太多的想象力,因为问题中就是这样写的。 - David Heffernan
不,那不是它的工作方式。文件映射是在其他地方创建的。我们只想打开它。我们有它的名字。你必须明白OpenFileMapping存在的原因。 - David Heffernan
我不确定为什么丹尼尔的答案被踩了。它是正确的。为了让Java程序访问文件映射,它必须被写入物理文件中。 - Breandán Dalton
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接