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()
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With