Search code examples
javabit-shiftrandomaccessfile

Bit shifting a RandomAccessFile


I need to bit shift everything in a RandomAccessFile that is to the right of the file-pointer four bytes to the right so that I can write an integer into it at the file pointer.

This will not compile:

raf >> 16;

I was going to use readFully() (which reads bytes from the RAF starting at the pointer) and then go from there, but that reads them into an array and a restriction of the project is that we can't use arrays.

How would I go about doing this?


Solution

  • A RandomAccessFile "works" on a physical file, it reads from and writes to a file.

    You can't just insert bytes into a position. All the bytes after the position have to be moved, copied to allow space for the value you want to insert.

    The most efficient way would be to read the remaining data into an array, insert (write) the new value and write back the array. But you said this is not allowed.

    Alternatively you have to use a loop (e.g. for) to iterate over the bytes and write them back to a greater position (the amount you want to insert: +4 bytes).

    Assuming the file length and current position is a multiple of 4 bytes (which suits your needs), here is an example how to do it:

    public static void insert(RandomAccessFile raf, int dataToInsert)
                          throws IOException {
    
        // First remember insertion position:
        long insPos = raf.getFilePointer();
    
        // Next copy all data from this pos. For easier, go downward:
        raf.seek(raf.length() - 4);
    
        for (long pos = raf.getFilePointer(); pos >= insPos; pos -= 4) {
            // readInt() and writeInt() implicitly moves the file pointer
            raf.writeInt(raf.readInt());
            raf.seek(pos - 4);
        }
    
        // Copy done, insert new value:
        raf.seek(insPos);
        raf.writeInt(dataToInsert);
    }
    

    Example Usage

    RandomAccessFile raf = new RandomAccessFile("a.txt", "rw");
    // Position file pointer where we want to insert:
    raf.seek(4);
    insert(raf, 0x41424344); // This is "ABCD" in text representation
    

    Input:

    123456789012
    

    Output:

    1234ABCD56789012