Search code examples
javarandomaccessfilehard-drive

Java Write Operation io_append io_write


I am triying to figure out how java writes bytes to disk.

If I look at the Randomaccesfile implementation, it has declared a native method and calls said native method to write to the disk when write(byte[]) is called.

source code for randomaccesfile:http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b27/java/io/RandomAccessFile.java#RandomAccessFile.writeBytes%28byte%5B%5D%2Cint%2Cint%29

private native void writeBytes(byte b[], int off, int len) throws IOException;

public void write(byte b[]) throws IOException {
    writeBytes(b, 0, b.length);
}

I searched inside the OpenJDK for writeBytes and found it inside io_util.c Here the functions IO_Append(fd, buf+off, len); and IO_Write(fd, buf+off, len); are called.

these functions can be found for Windows and Solaris inside the JDK in io_util_md.h

/*
* Route the routines
*/
#define IO_Sync fsync
#define IO_Read handleRead
#define IO_Write handleWrite
#define IO_Append handleWrite
#define IO_Available handleAvailable
#define IO_SetLength handleSetLength

Why can't i find the same for Linux?And what do io_append and io_write actually do?I can't find how they are implemented.


Solution

  • Seems that Solaris and Linux share the native code base for everything below http://hg.openjdk.java.net/jdk7/jdk7/jdk/

    io_util_md.h defines (for Solaris and Linux)

    #define IO_Append JVM_Write
    #define IO_Write JVM_Write 
    

    Now JVM_Write is defined in the hotspot code base, in jvm.cpp:

    JVM_LEAF(jint, JVM_Write(jint fd, char *buf, jint nbytes))
        JVMWrapper2("JVM_Write (0x%x)", fd);
        //%note jvm_r6
        return (jint)os::write(fd, buf, nbytes);
    JVM_END
    

    calling a OS dependent write function. The Linux implementation is in os_linux.inline.hpp

    inline size_t os::write(int fd, const void *buf, unsigned int nBytes) {
        size_t res;
        RESTARTABLE((size_t) ::write(fd, buf, (size_t) nBytes), res);
        return res;
    }