即我有一个10 mb的文件,我想删除1M到2M的字节,所以结果文件是9mb,其中以2m字节开始的数据到文件中现在是1M
我使用Java 7可以制作NIO,文件通常为10MB,并且经常通过网络访问,因此我正在寻找一种性能良好的优雅解决方案。
我知道BteBuffer.allocateDirect()和File.getChannel()但我正在努力解决是否有办法做我想做的事,而不必为了写回而从文件通道向临时缓冲区写入8MB提交到其他位置,或者如果使用allocateDirect(),实际上可以吗
我认为在磁盘上使用临时文件的方法是一种很好的方法。如果您可以在磁盘上创建新的临时文件,那么nio确实有一些选项可以为您提供帮助。我只是在这里使用API和nio教程,但似乎FileChannel.transferFrom
还是FileChannel.transferTo
您需要的工具。
我尚未测试以下代码,但它应为您指明正确的方向。
public static void main(String[] args) {
int megaByte = 1024 * 1024;
// prepare the paths
Path inPath = Paths.get("D:/file.dat"); // java.nio.file.Paths
Path outPath; // java.nio.file.Path
try {
outPath = Files.createTempFile(null, "swp"); // java.nio.file.Files
} catch (IOException ex) {
throw new IOError(ex);
}
// process the file
try (
FileChannel readChannel = new FileChannel.open(inPath, READ);
FileChannel writeChannel = new FileChannel.open(outPath, WRITE, TRUNCATE_EXISTING)
) {
long readFileSize = readChannel.size();
long expectedWriteSize = readFileSize;
if (readFileSize > 2 * megabyte)
expectedWriteSize = readFileSize - megabyte;
else if (readFileSize > megabyte)
expectedWriteSize = megabyte;
// copy first megabyte (or entire file if less than a megabyte)
long bytesTrans = readChannel.transferTo(0, megabyte, writeChannel);
// copy everything after the second megabyte
if (readFileSize > 2 * megabyte)
bytesTrans += readChannel.transferTo(2 * megabyte, readFileSize - 2 * megabyte, writeChannel);
if (bytesTrans != expectedWriteSize)
System.out.println("WARNING: Transferred " + bytesTrans + " bytes instead of " + expectedWriteSize);
} catch (FileNotFoundException ex) {
throw new RuntimeException("File not found!", ex);
} catch (IOException ex) {
throw new RuntimeException("Caught IOException", ex);
}
// replace the original file with the temporary file
try {
// ATOMIC_MOVE may cause IOException here . . .
Files.move(outPath, inPath, REPLACE_EXISTING, ATOMIC_MOVE);
} catch (IOException e1) {
try {
// . . . so it's probably worth trying again without that option
Files.move(outPath, inPath, REPLACE_EXISTING);
} catch (IOException e2) {
throw new IOError(e2);
}
}
}
即使您无法打开新文件,nio也可能会提供帮助。如果您打开文件的读/写通道或在同一文件上打开两个不同的通道,则可以使用该transferTo
方法将文件的一部分转移到文件的另一部分。我没有足够的经验来知道。API指出,采用显式位置参数(如的第一个参数transferTo
)的方法可以与写入文件的操作同时进行,因此我不排除它。如果尝试这样做,则可能需要以兆字节大小的块重写文件。如果这样行得通,那么FileChannel.truncate
当您将文件的某些部分写入到文件中较早的位置时,可以用它来截断文件的最后一个兆字节。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句