如何在Java中映射(mmap)linux块设备(例如/ dev / sdb)? [英] How to memory map (mmap) a linux block device (e.g. /dev/sdb) in Java?

查看:548
本文介绍了如何在Java中映射(mmap)linux块设备(例如/ dev / sdb)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以使用 java.nio 读取/编写带有Java的linux块设备。以下代码有效:

I can read/write a linux block device with Java using java.nio. The following code works:

Path fp = FileSystems.getDefault().getPath("/dev", "sdb");
FileChannel fc = null;
try {
  fc = FileChannel.open(fp, EnumSet.of(StandardOpenOption.READ, StandardOpenOption.WRITE));
} catch (Exception e) {
  System.out.println("Error opening file: " + e.getMessage());
}
ByteBuffer buf = ByteBuffer.allocate(50);
try {
  if(fc != null)
    fc.write(buf);
} catch (Exception e) {
  System.out.println("Error writing to file: " + e.getMessage());
}

但是,内存映射不起作用。以下代码失败

However, memory mapping does not work. The following code fails:

MappedByteBuffer mbb = null;
try {
  mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, 100);
} catch (IOException e) {
  System.out.println("Error mapping file: " + e.getMessage());
}

此失败并显示错误:

java.io.IOException: Invalid argument
    at sun.nio.ch.FileDispatcherImpl.truncate0(Native Method)
    at sun.nio.ch.FileDispatcherImpl.truncate(FileDispatcherImpl.java:79)
    at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:817)

这是否有解决方法?也许通过使用不同的库?我读到某个地方可能通过使用JNI我可以做到这一点,但我找不到任何来源。

Is there a work around to this? Perhaps by using a different library? I read somewhere that maybe by using JNI I could do this, but I couldn't find any sources.

推荐答案

根据文档实际映射文件的机制留给实现。似乎实现正在尝试截断文件(可能是因为块设备大小与您指定的大小不同?)。

According to the documentation the mechanics of actually mapping a file are left to the implementation. It appears that the implementation is attempting to truncate the file (maybe because the block device size is not the same as the size you specify?).

我很好奇为什么你直接从块设备读取(除非您尝试编写某种文件系统实用程序或需要执行原始I / O的操作)。如果您需要直接从块设备读取内存映射文件,您可能需要编写一些C / C ++代码来映射文件并处理读/写操作并使用Java / JNI桥接类来桥接对您的调用C / C ++代码。这样你就可以自己处理调用mmap()并指定你需要的任何选项。查看 mmap()文档,您可能无法在您的平台上指定块设备(我猜Linux但我可能错了)。

I am curious why you are reading from the block device directly (unless you are trying to write some sort of filesystem utility or something that needs to do raw I/O). If you need to read from the block device as a memory mapped file directly, you may need to write some C/C++ code to map the file and handle reading/writing to it and use a Java/JNI bridge class to bridge calls to your C/C++ code. That way you handle calling mmap() yourself and can specify any options you need. Looking at the mmap() documentation you may not be able to specify block devices on your platform (I'm guessing Linux but I could be wrong).

如果您绝对需要在Java中执行此操作,则可能需要执行read( )具有适当长度和偏移量的调用和write()调用。

If you absolutely need to do this within Java you may need to do read() calls and write() calls of the appropriate length and offset.

这篇关于如何在Java中映射(mmap)linux块设备(例如/ dev / sdb)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆