我需要在文本文件的开头写入一些内容。我有一个包含内容的文本文件,我想在此内容之前写一些内容。说我有;
先生下午好,今天过得怎么样?
我很好,你怎么样?
谢谢你的提问,我很好
修改后我希望是这样的:
第1页-场景59
2011 年 5 月 25 日先生下午好,今天过得怎么样?
我很好,你怎么样?
谢谢你的提问,我很好
刚刚编好的内容:)我怎样才能像这样修改文本文件?
您无法真正以这种方式修改 - 文件系统通常不允许您在任意位置插入数据 - 但您可以:
以防万一,这里对某人有用的是使用 Apache Commons IO 库将行添加到文件的方法的完整源代码。该代码不会将整个文件读入内存,因此适用于任何大小的文件。
public static void prependPrefix(File input, String prefix) throws IOException {
LineIterator li = FileUtils.lineIterator(input);
File tempFile = File.createTempFile("prependPrefix", ".tmp");
BufferedWriter w = new BufferedWriter(new FileWriter(tempFile));
try {
w.write(prefix);
while (li.hasNext()) {
w.write(li.next());
w.write("\n");
}
} finally {
IOUtils.closeQuietly(w);
LineIterator.closeQuietly(li);
}
FileUtils.deleteQuietly(input);
FileUtils.moveFile(tempFile, input);
}
我认为你想要的是随机访问。 查看相关的java教程。 但是,我不相信您可以在文件中的任意点插入数据;如果我没记错的话,你只会覆盖数据。 如果你想插入,你必须有你的代码
正如 @atk 所建议的,
java.nio.channels.SeekableByteChannel
是一个很好的界面。但仅从 1.7 开始可用。
更新:如果您使用 FileUtils 没有问题,则使用
String fileString = FileUtils.readFileToString(file);
这不是问题的直接答案,但文件通常是通过输入流访问的。如果这是您的用例,那么您可以通过
SequenceInputStream
链接输入流以实现相同的结果。例如
InputStream inputStream = new SequenceInputStream(new ByteArrayInputStream("my line\n".getBytes()), new FileInputStream(new File("myfile.txt")));
我会把它留在这里,以防万一有人需要
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try (FileInputStream fileInputStream1 = new FileInputStream(fileName1);
FileInputStream fileInputStream2 = new FileInputStream(fileName2)) {
while (fileInputStream2.available() > 0) {
byteArrayOutputStream.write(fileInputStream2.read());
}
while (fileInputStream1.available() > 0) {
byteArrayOutputStream.write(fileInputStream1.read());
}
}
try (FileOutputStream fileOutputStream = new FileOutputStream(fileName1)) {
byteArrayOutputStream.writeTo(fileOutputStream);
}
阅读atk的答案后,我想出了自己的实现:
/** Prepends the provided data to the very beginning of the file.<br>
* This functions works by overwriting the contents of the file block-by-block, first inserting the new data at the start, then
* proceeding to shift each block down until it reaches the end of the file, at which point the last 'previous' block is written.<br>
* <br>
* Note that while prepending large files will not take up any extra storage space or memory, the operation will take longer to
* complete, as it is necessary to re-write the entire file's contents once the operation has begun.
*
* @param data The data to prepend
* @param off The offset within the data to read from
* @param len The number of bytes to read within the data array
* @param file The file to prepend the data onto
* @throws IOException If an I/O error occurs while reading or writing to the file
* @author Brian_Entei */
public static final void prependBytes(byte[] data, int off, int len, File file) throws IOException {
// Insert-and-overwrite algorithm
// Could potentially optimize by setting a fixed buffer length (e.g. 4096), but will then need to update/manage how many bytes are read from the stream
final byte[] oldBuf = new byte[len];
final byte[] buf = new byte[oldBuf.length];
// Pre-load our prefix data into oldBuf
System.arraycopy(data, off, oldBuf, 0, len);
try(RandomAccessFile raf = new RandomAccessFile(file, "rw")) {
long pos = raf.getFilePointer();// store current file pointer (index into file, should be zero)
int length, oldLength = oldBuf.length;
while((length = raf.read(buf)) != -1) {// Let's read the first buffer (or 'block') of data
raf.seek(pos);// since we've just read from the stream and the pointer has been changed, roll it back so that we can overwrite what we just read
raf.write(oldBuf, 0, oldLength);// write the previously read data in the current data's place
oldLength = length;// store the currently read data's length ...
System.arraycopy(buf, 0, oldBuf, 0, length);// ... and data for the next loop iteration ...
pos = raf.getFilePointer();// ... as well as the pointer (since we've just read from the stream, thus advancing the index)
}
raf.write(oldBuf, 0, oldLength);// (don't forget to write the last bit of data once finished!)
}
}
/** Prepends the provided data to the very beginning of the file.<br>
* This functions works by overwriting the contents of the file block-by-block, first inserting the new data at the start, then
* proceeding to shift each block down until it reaches the end of the file, at which point the last 'previous' block is written.<br>
* <br>
* Note that while prepending large files will not take up any extra storage space or memory, the operation will take longer to
* complete, as it is necessary to re-write the entire file's contents once the operation has begun.
*
* @param data The data to prepend
* @param file The file to prepend the data onto
* @throws IOException If an I/O error occurs while reading or writing to the file
* @author Brian_Entei */
public static final void prependBytes(byte[] data, File file) throws IOException {
prependBytes(data, 0, data.length, file);
}
/** Example usage of {@linkplain #prependBytes(byte[], File)}.<br>
* <br>
* This method inserts the UTF-8 BOM into the start of the target file.
*
* @param file The text file
* @throws IOException If an I/O error occurs while reading or writing to the file */
public static final void insertUTF8BOM(File file) throws IOException {
prependBytes(new byte[] {(byte) 0xEF, (byte) 0xBB, (byte) 0xBF}, file);
}
此方法不会创建任何临时文件或占用大量内存,但会执行大量读取和写入操作。 事情可能可以进一步优化,但它对我来说已经足够好了。