我想创建一个简单的程序(用Java编写)来编辑文本文件 - 特别是在文本文件中随机位置插入任意文本的文件。此功能是我目前正在编写的更大程序的一部分。
阅读有关java.util.RandomAccessFile的描述,似乎在文件中间执行的任何写操作实际上都会覆盖现有内容。这是一个副作用,我想避免(如果可能的话)。
有没有一种简单的方法可以达到这个目的?
提前致谢。
答案 0 :(得分:16)
好的,这个问题很老了,但是自Java 1.4以来就存在FileChannels,我不知道为什么在处理文件中替换或插入内容的问题时没有提到它们。 FileChannels很快,使用它们。
这是一个例子(忽略异常和其他一些东西):
public void insert(String filename, long offset, byte[] content) {
RandomAccessFile r = new RandomAccessFile(new File(filename), "rw");
RandomAccessFile rtemp = new RandomAccessFile(new File(filename + "~"), "rw");
long fileSize = r.length();
FileChannel sourceChannel = r.getChannel();
FileChannel targetChannel = rtemp.getChannel();
sourceChannel.transferTo(offset, (fileSize - offset), targetChannel);
sourceChannel.truncate(offset);
r.seek(offset);
r.write(content);
long newOffset = r.getFilePointer();
targetChannel.position(0L);
sourceChannel.transferFrom(targetChannel, newOffset, (fileSize - offset));
sourceChannel.close();
targetChannel.close();
}
答案 1 :(得分:11)
嗯,不,我不相信有办法避免使用单个标准Java IO API调用覆盖现有内容。
如果文件不是太大,只需将整个文件读入ArrayList(每行一个条目),然后重写条目或为新行插入新条目。
然后用新内容覆盖现有文件,或将现有文件移动到备份并写入新文件。
根据编辑的复杂程度,您的数据结构可能需要更改。
另一种方法是在写入已编辑的文件时从现有文件中读取字符,并在读取时编辑流。
答案 2 :(得分:4)
如果Java有办法存储映射文件,那么你可以做的是将文件扩展到新的长度,映射文件,将所有字节存储到最后以创建漏洞并将新数据写入孔。
这适用于C.从未在Java中尝试过。
我想到的另一种方法是使用随机文件访问来做同样的事情。
使用更大的缓冲区大小以提高性能。
答案 3 :(得分:4)
您可以使用以下代码:
BufferedReader reader = null;
BufferedWriter writer = null;
ArrayList list = new ArrayList();
try {
reader = new BufferedReader(new FileReader(fileName));
String tmp;
while ((tmp = reader.readLine()) != null)
list.add(tmp);
OUtil.closeReader(reader);
list.add(0, "Start Text");
list.add("End Text");
writer = new BufferedWriter(new FileWriter(fileName));
for (int i = 0; i < list.size(); i++)
writer.write(list.get(i) + "\r\n");
} catch (Exception e) {
e.printStackTrace();
} finally {
OUtil.closeReader(reader);
OUtil.closeWriter(writer);
}
答案 4 :(得分:2)
我认为将文本插入现有文本文件的唯一方法是读取原始文件并将内容写入插入新文本的临时文件中。然后删除原始文件并将临时文件重命名为原始名称。
此example专注于将一行插入现有文件,但仍可能对您有用。
答案 5 :(得分:2)
我不知道除了
之外是否还有一种方便的方法关于目标:您可以在内存中构造文件的新内容,如果处理的文件不是那么大,则覆盖文件的旧内容。或者您可以将结果写入临时文件。
使用流可能最简单的事情,RandomAccessFile似乎不适合插入中间(afaik)。如果需要,请查看tutorial。
答案 6 :(得分:0)
如果是文本文件,,,,请读取StringBuffer中的现有文件,并将新内容附加到同一个StringBuffer中,现在您可以在文件中写入SrtingBuffer。所以现在该文件包含现有文本和新文本。