在 Java 中将行添加到文件中
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2537944/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Prepend lines to file in Java
提问by folone
Is there a way to prepend a line to the File in Java, without creating a temporary file, and writing the needed content to it?
有没有办法在 Java 中为文件添加一行,而无需创建临时文件,并将所需的内容写入其中?
回答by Stephen C
No, there is no way to do that SAFELYin Java.
不,在 Java 中没有办法安全地做到这一点。
No filesystem implementation in any mainstream operating system supports this kind of thing, and you won't find this feature supported in any mainstream programming languages.
任何主流操作系统中都没有文件系统实现支持这种东西,你也不会发现任何主流编程语言都支持这种特性。
Real world file systems are implemented on devices that store data as fixed sized "blocks". It is not possible to implement a file system model where you can insert bytes into the middle of a file without significantly slowing down file I/O, wasting disk space or both.
现实世界的文件系统是在将数据存储为固定大小的“块”的设备上实现的。不可能实现一个文件系统模型,您可以在其中插入字节到文件中间而不显着减慢文件 I/O、浪费磁盘空间或两者兼而有之。
The solutions that involve an in-place rewrite of the file are inherently unsafe. If your application is killed or the power dies in the middle of the prepend / rewrite process, you are likely to lose data. I would NOT recommend using that approach in practice.
涉及文件就地重写的解决方案本质上是不安全的。如果您的应用程序在 prepend/rewrite 过程中被终止或电源中断,您很可能会丢失数据。我不建议在实践中使用这种方法。
Use a temporary file. It is safer.
使用临时文件。它更安全。
回答by sfussenegger
There is a way, it involves rewriting the whole file though (but no temporary file). As others mentioned, no file system supports prepending content to a file. Here is some sample code that uses a RandomAccessFile to write and read content while keeping some content buffered in memory:
有一种方法,它涉及重写整个文件(但没有临时文件)。正如其他人提到的,没有文件系统支持将内容添加到文件中。下面是一些示例代码,它使用 RandomAccessFile 来写入和读取内容,同时将一些内容缓存在内存中:
public static void main(final String args[]) throws Exception {
File f = File.createTempFile(Main.class.getName(), "tmp");
f.deleteOnExit();
System.out.println(f.getPath());
// put some dummy content into our file
BufferedWriter w = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f)));
for (int i = 0; i < 1000; i++) {
w.write(UUID.randomUUID().toString());
w.write('\n');
}
w.flush();
w.close();
// append "some uuids" to our file
int bufLength = 4096;
byte[] appendBuf = "some uuids\n".getBytes();
byte[] writeBuf = appendBuf;
byte[] readBuf = new byte[bufLength];
int writeBytes = writeBuf.length;
RandomAccessFile rw = new RandomAccessFile(f, "rw");
int read = 0;
int write = 0;
while (true) {
// seek to read position and read content into read buffer
rw.seek(read);
int bytesRead = rw.read(readBuf, 0, readBuf.length);
// seek to write position and write content from write buffer
rw.seek(write);
rw.write(writeBuf, 0, writeBytes);
// no bytes read - end of file reached
if (bytesRead < 0) {
// end of
break;
}
// update seek positions for write and read
read += bytesRead;
write += writeBytes;
writeBytes = bytesRead;
// reuse buffer, create new one to replace (short) append buf
byte[] nextWrite = writeBuf == appendBuf ? new byte[bufLength] : writeBuf;
writeBuf = readBuf;
readBuf = nextWrite;
};
rw.close();
// now show the content of our file
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(f)));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
回答by Ignacio Vazquez-Abrams
No. There are no "intra-file shift" operations, only read and write of discrete sizes.
不。没有“文件内移位”操作,只有离散大小的读写。
回答by Kevin Reid
It would be possible to do so by reading a chunk of the file of equal length to what you want to prepend, writing the new content in place of it, reading the later chunk and replacing it with what you read before, and so on, rippling down the to the end of the file.
可以通过读取与您想要添加的内容相同长度的文件块来做到这一点,写入新内容代替它,读取后面的块并将其替换为您之前阅读的内容,依此类推,向下滚动到文件末尾。
However, don't do that, because if anything stops (out-of-memory, power outage, rogue thread calling System.exit) in the middle of that process, data will be lost. Use the temporary file instead.
但是,不要这样做,因为如果System.exit在该过程中间发生任何事情(内存不足、断电、恶意线程调用),数据将会丢失。请改用临时文件。
回答by Ham Vocke
You could store the file content in a String and prepend the desired line by using a StringBuilder-Object. You just have to put the desired line first and then append the file-content-String.
No extra temporary file needed.
您可以将文件内容存储在 String 中,并使用 StringBuilder-Object 在所需的行之前。您只需要首先放置所需的行,然后附加文件内容字符串。
不需要额外的临时文件。
回答by Dinesh Kumar
private static void addPreAppnedText(File fileName) {
FileOutputStream fileOutputStream =null;
BufferedReader br = null;
FileReader fr = null;
String newFileName = fileName.getAbsolutePath() + "@";
try {
fileOutputStream = new FileOutputStream(newFileName);
fileOutputStream.write("preappendTextDataHere".getBytes());
fr = new FileReader(fileName);
br = new BufferedReader(fr);
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null) {
fileOutputStream.write(("\n"+sCurrentLine).getBytes());
}
fileOutputStream.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileOutputStream.close();
if (br != null)
br.close();
if (fr != null)
fr.close();
new File(newFileName).renameTo(new File(newFileName.replace("@", "")));
} catch (IOException ex) {
ex.printStackTrace();
}
}
}

