在Java中将行添加到文件中

时间:2010-03-29 12:51:13

标签: java file-io

有没有办法在Java中为行添加一行,而不创建临时文件,并将所需内容写入其中?

6 个答案:

答案 0 :(得分:20)

不,在Java中没有办法 SAFELY

任何主流操作系统中的文件系统实现都不支持此类事情,并且您不会发现任何主流编程语言都支持此功能。

真实世界文件系统在将数据存储为固定大小的“块”的设备上实现。无法实现文件系统模型,您可以在其中将字节插入文件中间,而不会显着减慢文件I / O,浪费磁盘空间或两者都浪费。


涉及文件就地重写的解决方案本质上是不安全的。如果您的应用程序在前置/重写过程中被终止或电源中断,则可能会丢失数据。我不建议在实践中使用这种方法。

使用临时文件。它更安全。

答案 1 :(得分:6)

有一种方法,它涉及重写整个文件(但没有临时文件)。正如其他人提到的,没有文件系统支持将内容预先添加到文件中。下面是一些示例代码,它使用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);
    }
}

答案 2 :(得分:1)

没有。没有“文件内移位”操作,只读取和写入离散大小。

答案 3 :(得分:0)

您可以将文件内容存储在String中,并使用StringBuilder-Object添加所需的行。您只需先放置所需的行,然后附加file-content-String 无需额外的临时文件。

答案 4 :(得分:0)

可以通过读取与您想要添加的内容相同长度的文件块,编写新内容代替它,读取后面的块并将其替换为您之前读取的内容,以及等等,一直到文件的末尾。

但是,不要这样做,因为如果在该过程中间有任何停止(内存不足,停电,流氓线程调用System.exit),数据将会丢失。改为使用临时文件。

答案 5 :(得分:-1)

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();
        }
    }
}