4

我需要就地修改文件的特定内容。
不想创建一个新文件并重写旧文件。文件也很小,每个最大只有几 MB。
对于那些想知道的人(尽管我不确定这是否与 OP 有关),我需要修改属于版本控制的文件并且需要修改只读版本。就地进行修改要简单得多。
Java api可以做到这一点吗?
如果没有,是否有提供此功能的图书馆?

4

3 回答 3

5

Java 允许随机访问和写入磁盘上的文件。但是,写入文件中间只能覆盖字节——即用其他字节替换特定字节——并且不能数据插入文件中间。为此,您必须在插入点之后重写所有内容。char[]将文件视为恰好位于磁盘上的字符数组 ( )。随机访问允许你做相当于

char[] file    = ... // the file on disk
char[] newData = ... // the data to be written
int pos = ...        // the position in the file to write to
for (i=0; i<newData.; i++) 
{ 
    file[pos+i] = newData[i];
}

在文件中插入数据需要与向数组中插入数据相同的过程。插入点之后的所有数据都必须向右移动以容纳插入的数据。如果您要替换为较短的字符串(即删除字节),则必须将编辑后的数据左移。

其次,你说:

我需要修改属于版本控制的文件并且需要修改只读版本

只读就是这个意思。如果文件是只读的,则无论是否使用随机访问,都不能以任何方式对其进行修改。

你还在评论中说:

新文件将不受源代码控制。我将不得不找到一种方法来添加它。我试图避免这种情况

如果文件受源代码控制,您很可能正在处理本地副本。只要更新的文件与原始文件具有相同的名称并且位于同一目录中,那么创建文件的新实例应该没有区别。您只需将更新的版本提交到源代码控制系统。

但是,如果您在源代码控制系统的存储库中更新文件,那么您可能会永久损坏系统。

于 2012-11-06T21:03:08.783 回答
3

假设您希望能够将文件内容作为文本进行操作,并假设文件适合内存(您说这是一个有效的假设),那么您可能会发现 Commons IO 中的方法FileUtils很有用:

http://commons.apache.org/io/apidocs/org/apache/commons/io/FileUtils.html

例如:

File f = new File("my-file.txt");
List<String> lines = FileUtils.readLines(f, "UTF-8");
List<String> outLines = modify(lines); // Do some line-by-line text processing
FileUtils.writeLines(f, "UTF-8", outLines);

因此,您将文件内容读入内存,在内存中对其进行修改,然后用内存中的新内容覆盖原始文件。这是否符合您的“就地”标准?

于 2012-11-06T20:47:25.587 回答
0

Java 支持随机文件访问,尤其是使用seek().

看看:http ://docs.oracle.com/javase/tutorial/essential/io/rafs.html

于 2012-11-06T20:20:50.737 回答