简体   繁体   English

使用Java删除文件的最后一行

[英]Deleting the last line of a file with Java

I have a .txt file, which I want to process in Java. 我有一个.txt文件,我想用Java处理它。 I want to delete its last line. 我想删除它的最后一行。

I need ideas on how to achieve this without having to copy the entire content into another file and ignoring the last line. 我需要有关如何实现这一点的想法,而无需将整个内容复制到另一个文件中并忽略最后一行。 Any suggestions? 有什么建议?

您可以通过扫描文件找到最后一行的开头,然后使用FileChannel.truncateRandomAccessFile.setLength截断它。

By taking RandomAccessFile you can: 通过使用RandomAccessFile,您可以:

  • use method seek(long) to jump forward and read those lines. 使用方法seek(long)向前跳并读取这些行。 But you won't know exactly how big the jump should be. 但你不会确切地知道跳跃应该有多大。
  • to delete last lines you need the position of begin of last line so before reading each line store their file pointer position (method getFilePointer() ). 要删除最后一行,你需要最后一行开头的位置,所以在读取每一行之前,存储它们的文件指针位置(方法getFilePointer() )。 Deleting to that position you use setLength(long) . 删除到该位置使用setLength(long)

Code would be something like this: 代码将是这样的:

    LinkedList<String> lines=null;
    int howMuch = 1; // one line to read and delete
    try{
        RandomAccessFile raf = new RandomAccessFile(inputFileName, "rw");

        System.out.println("File Length="+raf.length());

        long step = 20;  // here I advice to write average length of line
        long jump = raf.length()<step*howMuch?
                0:
                    raf.length()-step*howMuch; 
        raf.seek(jump);
        lines = new LinkedList<String>();
        LinkedList<Long> pos = new LinkedList<Long>();

        Entry<LinkedList<String>,LinkedList<Long>> rLinesRead = getRemainingLines(raf,
                new AbstractMap.SimpleEntry<LinkedList<String>,LinkedList<Long>> (lines,pos));
        while(rLinesRead.getKey().size()<howMuch){
            if(jump<step)
                if(jump<=0)
                    break;
                else{
                    jump=0;
                    raf.seek(jump);
                    rLinesRead=getRemainingLines(raf,rLinesRead);
                    break;
                }
            else
                jump=jump-step;
            raf.seek(jump);
            rLinesRead=getRemainingLines(raf,rLinesRead);
        }
        int originalSize=rLinesRead.getKey().size(); 
        lines=rLinesRead.getKey();
        pos=rLinesRead.getValue();
        for (int i=0;i<originalSize-howMuch;++i){
            lines.removeFirst();
            pos.removeFirst();
        }
        if(!pos.isEmpty())
            raf.setLength(pos.getFirst()); // before last(from EOF) returned fully read lines in file          
    }catch(Exception ex){
        ex.printStackTrace();
    } finally{
        try {               raf.close();            } catch (Exception e) {             e.printStackTrace();            }
    }
//returns line to EOF with their begin file pointer positions
private Entry<LinkedList<String>,LinkedList<Long>> getRemainingLines(RandomAccessFile raf,
        Entry<LinkedList<String>,LinkedList<Long>> linesAlreadyLoadedFromEnd) throws IOException{
    LinkedList<String> pLines = linesAlreadyLoadedFromEnd.getKey();
    LinkedList<Long> pPos = linesAlreadyLoadedFromEnd.getValue();

    long init=raf.getFilePointer();
    String str = raf.readLine();
    if(pPos.size()>0?pPos.getFirst()==0:false || str==null)
        return linesAlreadyLoadedFromEnd;

    LinkedList<String> lines = new LinkedList<String>();
    LinkedList<Long> pos = new LinkedList<Long>();
    if(init==0L ){              
        lines.add(str);
        pos.add(0L);
    }
    Long tmpPos = raf.getFilePointer();
    while ((str = raf.readLine())!=null && !pPos.contains(tmpPos)){
        lines.add(str);
        pos.add(tmpPos);
        tmpPos = raf.getFilePointer();
    }
    pLines.addAll(0,lines);
    pPos.addAll(0,pos);
    return new AbstractMap.SimpleEntry<LinkedList<String>,LinkedList<Long>> (pLines,pPos);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM