2023-01-19 376
我可以使用java.nio使用Java读取/编写Linux Block设备.以下代码有效:
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());
}
但是,内存映射不起作用.以下代码失败:
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可以做到的,但是我找不到任何来源.
根据文档实际映射文件的机制保留到实施中.看来该实现正在尝试截断文件(也许是因为块设备的大小与您指定的大小不同吗?).
我很好奇您为什么直接从块设备上读取(除非您试图编写某种文件系统实用程序或需要进行RAW I/O的某些内容).如果您需要直接从块设备读取作为内存映射的文件,则可能需要编写一些C/C ++代码来映射文件并将读取/写入给它,并使用Java/Jni Bridge类以将桥式调用桥接到您的C/C ++代码.这样,您可以自己调用MMAP()并可以指定所需的任何选项.查看 mmap()文档您可能无法在您的平台上指定块设备(我猜是Linux,但我可能错了).
如果您绝对需要在Java中执行此操作,则可能需要进行读取()呼叫和witter()呼叫()适当的长度和偏移.
我发现最简单的方法是使用 jna sun.*/com.sun.*魔术.首先,您需要包装libc这样:
import com.sun.jna.LastErrorException;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
public interface LibC extends Library {
LibC instance = (LibC) Native.loadLibrary("c", LibC.class);
Pointer mmap(Pointer address, long length,
int protect, int flags, int fd,
long offset) throws LastErrorException;
// implement more methods if you like
}
,然后您几乎完成了!您需要的只是获取文件描述符.这可能有点棘手:
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
int fd = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess()
.get(randomAccessFile.getFD());
就是这样.现在您可以从Java致电libc:
Pointer result = LibC.instance.mmap(
/*pass your desired parameters along with obtained fd*/
);
filechannel.map尝试将文件截断为指定的大小:请参阅实现
您需要获取块设备的大小,并将该精确的大小传递给地图调用.
不用担心实际设备的大小是否大于可用内存.该操作系统将根据需要处理内存和退出的交换页面.
以上所述是小编给大家介绍的如何在Java中映射(mmap)linux块设备(例如/dev/sdb)?,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!
原文链接:https://77isp.com/post/25883.html
=========================================
https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。
数据库技术 2022-03-28
网站技术 2022-11-26
网站技术 2023-01-07
网站技术 2022-11-17
Windows相关 2022-02-23
网站技术 2023-01-14
Windows相关 2022-02-16
Windows相关 2022-02-16
Linux相关 2022-02-27
数据库技术 2022-02-20
抠敌 2023年10月23日
嚼餐 2023年10月23日
男忌 2023年10月22日
瓮仆 2023年10月22日
簿偌 2023年10月22日
扫码二维码
获取最新动态