Java - delete line from text file by overwriting while reading it

后端 未结 3 1860
离开以前
离开以前 2020-11-27 07:59

I\'m trying to delete a line of text from a text file without copying to a temporary file. I am trying to do this by using a Printwriter and a Scanner and having them traver

3条回答
  •  暖寄归人
    2020-11-27 09:02

    As others have pointed out, you might be better off using a temporary file, if there's a slightest risk that your program crashes mid way:

    public static void removeNthLine(String f, int toRemove) throws IOException {
    
        File tmp = File.createTempFile("tmp", "");
    
        BufferedReader br = new BufferedReader(new FileReader(f));
        BufferedWriter bw = new BufferedWriter(new FileWriter(tmp));
    
        for (int i = 0; i < toRemove; i++)
            bw.write(String.format("%s%n", br.readLine()));
    
        br.readLine();
    
        String l;
        while (null != (l = br.readLine()))
            bw.write(String.format("%s%n", l));
    
        br.close();
        bw.close();
    
        File oldFile = new File(f);
        if (oldFile.delete())
            tmp.renameTo(oldFile);
    
    }
    

    (Beware of the sloppy treatment of encodings, new-line characters and exception handling.)


    However, I don't like answering questions with "I won't tell you how, because you shouldn't do it anyway.". (In some other situation for instance, you may be working with a file that's larger than half your hard drive!) So here goes:

    You need to use a RandomAccessFile instead. Using this class you can both read and write to the file using the same object:

    public static void removeNthLine(String f, int toRemove) throws IOException {
        RandomAccessFile raf = new RandomAccessFile(f, "rw");
    
        // Leave the n first lines unchanged.
        for (int i = 0; i < toRemove; i++)
            raf.readLine();
    
        // Shift remaining lines upwards.
        long writePos = raf.getFilePointer();
        raf.readLine();
        long readPos = raf.getFilePointer();
    
        byte[] buf = new byte[1024];
        int n;
        while (-1 != (n = raf.read(buf))) {
            raf.seek(writePos);
            raf.write(buf, 0, n);
            readPos += n;
            writePos += n;
            raf.seek(readPos);
        }
    
        raf.setLength(writePos);
        raf.close();
    }
    

提交回复
热议问题