如何以Java方式直接读/写文件(如O_DIRECT标志的效果)?

2022-09-03 16:04:11

我必须直接读/写文件,没有任何缓冲。在旧的C方式中,我通过使用带有标志的open方法来做到这一点。O_DIRECT

这在Java方式中可能吗?

这是描述O_DIRECT

尝试最大程度地减少与此文件之间的 I/O 的缓存影响。通常,这会降低性能,但在特殊情况下很有用,例如当应用程序执行自己的缓存时。文件 I/O 直接在用户空间缓冲区之间完成。

更新:

这是我的代码示例,

// write
fos = new FileOutputStream(fileName);
fos.write(inputData);
fos.flush();
fos.close();

// read
fis = new FileInputStream(fileName);
int len = fis.read(outputData, offset, length);
fis.close();

背景是,我将数据(实际上是命令)写入sd卡(某种智能卡)上的文件,然后智能卡接收命令并将结果准备到同一文件。通常,我可以只从该文件中读取数据(结果),但是我得到了相同的结果,也就是说,我刚刚恢复了我的命令。这是意想不到的结果。我怀疑代码是否只是写入/读取到缓冲区和从缓冲区读取,而不是实际文件。刷新不起作用。inputDataoutputData


答案 1

FileOutputStream的Android文档明确指出它是一个无缓冲流。无论如何,flush() 后跟 close() 应该可以解决问题。在 close() 之前,您可能想要采取的唯一额外步骤是 getFD().sync()。

您提到了智能卡,因此此设备实现了自己的(假)文件系统,显示为SD卡或类似主机。卡片的文档是否说明您应该给卡片多长时间才能注意到文件的更改?在块 I/O 级别,没有相应的“打开”或“关闭”操作,因此设备应注意字节的写入。

或者,如果设备是“聪明的”,并且使用对文件元数据上的时间更改,那么你可能需要调用File.setLastModified(System.currentTimeMillis())来手动“触摸”文件。假设类似 sd 的设备使用“noatime”选项进行安装,以提高性能。


答案 2

当您调用 时,与文件描述符关联的所有数据都将消失。由于您获得的输入数据与输出数据相同,因此这可能不是 Java 文件读取问题。close()

我建议您从Linux调试设备(驱动程序),而不是从Android调试。如果您愿意,可以编写一个 C 程序来执行相同的操作,并尝试从 adb shell 运行它。它应该可以帮助您找出原始问题。