Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to directly read/write file from and to device (like effect of O_DIRECT flag) in Java way?

I have to read/write files directly, without any buffering. In old C way, I did this by using of open method with O_DIRECT flag.

Is this possible in Java way?

Here's O_DIRECT description

Try to minimize cache effects of the I/O to and from this file. In general this will degrade performance, but it is useful in special situations, such as when applications do their own caching. File I/O is done directly to/from user space buffers.

UPDATED:

Here's my code sample,

// 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();

The background was that I wrote data (actually, command) to a file on sd card (some kind of smartcard), then smartcard received command and prepared result to the same file. Normally, I can just read the data (result) from that file, but I got same inputData and outputData, namely, I just got my command back. That's unexpected result. I'm suspecting if the code just wrote/read to and from a buffer, not the real file. Flush failed to work.

like image 435
fifth Avatar asked Jul 06 '12 03:07

fifth


2 Answers

The android docs for FileOutputStream explicitly note that it is an unbuffered stream. Regardless, flush() followed by close() should do the trick. The only additional step you may want to take before close() is getFD().sync().

You mention a smart card, therefore this device implements its own (fake) file-system, appearing as an SD card or such to the host. Does the card's docs say how long you should give the card to notice changes to the file? At the block I/O level there is no corresponding 'open' or 'close' operation, therefore the device should notice the writes of the bytes.

Alternately if the device is 'clever' and uses changes to the time on the file metadata, then you may need to call File.setLastModified(System.currentTimeMillis()) to 'touch' the file manually. Assuming the sd-like device is mounted with the 'noatime' option to improve performance.

like image 71
caskey Avatar answered Oct 02 '22 09:10

caskey


When you call close(), all data associated with the file descriptor is gone. Since you are getting the same input data as output data, this may not be a Java file reading problem.

I suggest that you debug your device (driver) from Linux, rather than from Android. If you prefer, write a C program to do the same thing, and try to run it from the adb shell. It should help you to figure out the original problem.

like image 27
Durairaj Packirisamy Avatar answered Oct 02 '22 07:10

Durairaj Packirisamy