Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way of deleting a section of a binary file in Java 7

Tags:

java

nio

i.e I have a 10 mb file, and I want to remove bytes 1M to 2M so the resultant file is 9mb, with the data that was starting at 2m bytes into the file now starting at 1M

Im using Java 7 so can make of NIO, files typically 10MB in size and often accessed over the network so Im looking for an elegant solution that performs well.

Im aware of BteBuffer.allocateDirect() and File.getChannel() but Im struggling to work out if there is way to do what I want which doesnt involve having to write 8MB from file channel to a temporary buffer just in order to write it back to file in a different place, or is this actually okay if using allocateDirect()

like image 832
Paul Taylor Avatar asked Sep 25 '15 16:09

Paul Taylor


1 Answers

Write the result to a temporary file, then replace the old file with your temporary file (which acts as a buffer on disk).

Code example:

public static void main(String[] args) {
    // -- prepare files
    File inFile = new File("D:/file.dat");
    File outFile;
    try {
        outFile = File.createTempFile("swap", "buffer");
    } catch (IOException ex) {
        throw new IOError(ex);
    }

    // -- process file
    try (
            InputStream inStream = new FileInputStream(inFile);
            OutputStream outStream = new FileOutputStream(outFile)
    ) {
        //drop some bytes      (will be removed)
        inStream.skip(4);
        //modify some bytes    (will be changed)
        for (int i = 0; i < 4; i++) {
            byte b = (byte) inStream.read();
            outStream.write(b >> 4);
        }
        //copy bytes in chunks (will be kept)
        final int CHUNK_SIZE = 1024;
        byte[] chunkBuffer = new byte[CHUNK_SIZE];
        while (true) {
            int chunkSize = inStream.read(chunkBuffer, 0, CHUNK_SIZE);
            if (chunkSize < 0) {
                break;
            }
            outStream.write(chunkBuffer, 0, chunkSize);
        }
    } catch (FileNotFoundException ex) {
        throw new RuntimeException("input file not found!", ex);
    } catch (IOException ex) {
        throw new RuntimeException("failed to trim data!", ex);
    }

    // -- release changes
    //replace inFile with outFile
    inFile.delete();
    outFile.renameTo(inFile);
}
like image 57
Binkan Salaryman Avatar answered Sep 20 '22 00:09

Binkan Salaryman