18

I have a C++ program that uses at one point

hMapFile = OpenFileMapping(dwDesiredAccess, bInheritHandle, lpName);

The lpName is something like "myfile" without extensions or path, i.e. a memory mapped file. I can find the file with the WinObj-Browser (WinObj) in the path Sessions\1\BaseNamedObjects\myfile. If I try to read that particular file in Java, I tried

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

But I get always the same error: Cannot find the specified file at the RandomAccessFile command. Maybe another file-access is needed? Which one?

As I understand by other posts, they always use a path and an extension, however, I have no idea that the path and extension would be in my case...

What I'm looking for, I a way to access the Kernel object namespacesKernel object namespaces

I know, there is this JNI example (Memorymap using JNI), however I would like to keep it simple and use nio (if even possible).

UPDATE

So I just tried the whole thing in C# and it was ridiculously easy, didn't take me more than 5 lines of code.

rst
  • 2,510
  • 4
  • 21
  • 47
  • 1
    What is the current working directory of the C++ program? That is where the file is created. If you don't specify an absolute path, the filename is created in the relative path from the process current working directory. If the two working directories of the C++ and the Java programs are not the same, you can't really use relative path, you should specify an absolute path, same in both programs, to find the file. – Some programmer dude Jun 22 '15 at 07:25
  • @ErwinBolwidt: Yes it does exist, I wrote in the question, that I can access that file while testing the Java app in the winobj browser. @JoachimPileborg: It is something like `C:\Project\server\`, stupid question: the file is not visible in the `explorer`, but I guess it shouldn't? – rst Jun 22 '15 at 07:29
  • 1
    The file mapping object is not part of the file system. Working directory is not relevant. You will also need to call `OpenFileMapping`. `RandomAccessFile` won't do that. – David Heffernan Jun 22 '15 at 08:07
  • @DavidHeffernan: AFAIK `OpenFileMapping` does not exist in Java, what would be the equivalent? – rst Jun 22 '15 at 08:10
  • 1
    I don't know if the Java libraries support opening a named mapping. `MappedByteBuffer` seems to require you to have a file system file name at hand. I'd be inclined to use JNI or JNA. – David Heffernan Jun 22 '15 at 08:12

2 Answers2

1

A file is a file, I agree with "Joachim Pileborg" that the Java program has not got the file in its working directory. Try

String working dir = System.getProperty("user.dir");

and make sure the file is in the correct path.

Konrad Lindenbach
  • 4,911
  • 1
  • 26
  • 28
kaifong
  • 342
  • 2
  • 6
  • Hi, that won't work, check "Non-persisted memory-mapped files" in https://msdn.microsoft.com/en-us/library/dd997372%28v=vs.110%29.aspx . I'm talking about shared memory for IPC – rst Oct 20 '15 at 06:44
0

You need to use CreateFileMapping instead of OpenFileMapping. That way you will create an actual file on the disk which is associated with the file mapping.

Note: It is important to notice that using regular Read/Write methods will NOT be synchronized with a file mapping of a different process. So you still need to use something like MappedByteBuffer in Java

Daniel
  • 1,041
  • 7
  • 13
  • I think asker wants to open an existing mapping, one created by a different process – David Heffernan Jun 22 '15 at 08:54
  • @DavidHeffernan: Yes. I understood that as well. CreateFileMapping will create a new OR open an existing file mapping which is based on a REAL file (instead of OpenFileMapping which will either open an existing mapping OR create a new one which is NOT based on any real file. – Daniel Jun 22 '15 at 09:02
  • CreateFileMapping requires a file handle. It seems to me that the user won't be able to obtain that file handle. So, OpenFileMapping is what is needed. – David Heffernan Jun 22 '15 at 09:03
  • Obtaining a file handle is something as difficult as `CreateFile` with a specific file name. It is possible to use a different handle (to the same file) in each process. And using a file name it is possible to create a MappedByteBuffer object... – Daniel Jun 22 '15 at 09:09
  • Why would the user know that specific file name? I'm imagining that the user only has the name of the file mapping object. And that's not really taking much imagination since it is what is written in the question. – David Heffernan Jun 22 '15 at 09:15
  • What is the question about? "How do I open a file mapping in JAVA". Short answer: you don't unless the file mapping is based on a real file. Long answer: You first need to provide a file (yes, we create a new one with a known name). Then we can create a file mapping on it. Then we can open that file (with the known file name...) from within Java. (I assume that if the name of the mapping can be shared, we can also share the name of a real file). – Daniel Jun 22 '15 at 09:23
  • No. That's not how it goes. The file mapping is created elsewhere. We just want to open it. We have its name. You must appreciate that OpenFileMapping exists for a reason. – David Heffernan Jun 22 '15 at 09:24
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/81159/discussion-between-daniel-and-david-heffernan). – Daniel Jun 22 '15 at 09:25
  • Dear Daniel, it is not possible for me to change the C++ application – rst Jun 22 '15 at 09:59
  • I'm not sure why Daniel's answer was downvoted. It is correct. In order for a Java program to get access to the file mapping, it has to be written to a physical file. – Breandán Dalton Oct 17 '15 at 19:52