各位师兄:
  请教一下,JAVA如何实现读取文件时,从文件的最后一行往上一行行读出来。
我的文件是已经生成稳定的,不会再增加内容了。我只需要读取时,从文件的最后一行读起,一次向上读取一行。
JAVA中可以实现这样的功能吗?谢谢指教。

解决方案 »

  1.   

    readline()方法嵌套在for 循环里应该可以把
      

  2.   

    用RandomAccessFile,把文件指针定位到最后一行.
      

  3.   

    以下是随便写的代码,主要是提供思路,需要调试的。下班了,没时间调了
    RandomAccessFile r = null;
    // LineNumberReader lnr = new LineNumberReader(new FileReader(file));
    // ArrayList al = new ArrayList();
    try{
    r = new RandomAccessFile(file,"r");
    long start = r.getFilePointer();
    long cur = start + r.length()-1;
    String result = "";
    r.seek(cur);
    int c=-1;
    while(cur>=start){
    c = r.read();
    if(c=='\n'||c=='\r'){
    r.seek(cur+1);
    result = r.readLine();
    // do more handle about the result here
    // ...
    }
    cur--;
    }
    }finally{
    if(r!=null)
    r.close();
    }
      

  4.   

    在4楼的基础上,我修改了一下,整理出来了从文件末尾读取文件的程序:
    package rfile;import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.RandomAccessFile;public class FromEndRF {
    public static void main(String args[]){
    try {
    RandomAccessFile rf=new RandomAccessFile("H:/JSP/tech/login.jsp","r");
    long len=rf.length();
    long start=rf.getFilePointer();
    System.out.println(start);
    long nextend=start+len-1;
    String line;
    rf.seek(nextend);
    int c=-1;
    while(nextend>start){
    c=rf.read();
    if(c=='\n'||c=='\r'){
    line=rf.readLine();
    System.out.println(line);
    }
    nextend--;
    rf.seek(nextend);
    if(nextend==0){//当文件指针退至文件开始处,输出第一行
    System.out.println(rf.readLine());
    }
    }
    } catch (FileNotFoundException e) {
    e.printStackTrace();
    } catch (IOException e) {
    e.printStackTrace();
    }
    finally{
    try {
    rf.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    }
      

  5.   

    楼上的有算法和语法问题,会多打印出一行空行
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.RandomAccessFile;public class FromEndRF {
      public static void main(String args[]) {
        RandomAccessFile rf = null;
        try {
          rf = new RandomAccessFile("d:\\2.txt", "r");
          long len = rf.length();
          long start = rf.getFilePointer();
          System.out.println(start);
          long nextend = start + len - 1;
          String line;
          rf.seek(nextend);
          int c = -1;
          while (nextend > start) {
            c = rf.read();
            if (c == '\n' || c == '\r') {
              line = rf.readLine();
              System.out.println(line);
              nextend--;
            }
            nextend--;
            rf.seek(nextend);
            if (nextend == 0) {// 当文件指针退至文件开始处,输出第一行
              System.out.println(rf.readLine());
            }
          }
        } catch (FileNotFoundException e) {
          e.printStackTrace();
        } catch (IOException e) {
          e.printStackTrace();
        } finally {
          try {
            if (rf != null)
              rf.close();
          } catch (IOException e) {
            e.printStackTrace();
          }
        }
      }
    }
      

  6.   

    如果最后一行是空行时,为什么执行下面代码会打出个null???
    if (c == '\n' || c == '\r') {
              line = rf.readLine();
              System.out.println(line);
              nextend--;
            }
      

  7.   

    经6楼提醒,我突然发现,确实多打印了一行空行,谢谢6楼在此基础上解决了这个问题,学习了!至于最后一行是空行时,会打印出null,我当时也知道这个情况,只是当时没有解决得了,希望大家一起参与解决。
      

  8.   

    // 1 解决编码问题
    // 2 null 代表这一行到了文件末尾,而且啥也没有读到,而且这是API里面说明的
    // null if end of file is encountered before even one byte is readpackage test;import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.RandomAccessFile;public class FromEndRF {
      public static void read(String filename) {
        read(filename, "GBK");
      }  public static void read(String filename, String charset) {    RandomAccessFile rf = null;
        try {
          rf = new RandomAccessFile(filename, "r");
          long len = rf.length();
          long start = rf.getFilePointer();
          long nextend = start + len - 1;
          String line;
          rf.seek(nextend);
          int c = -1;
          while (nextend > start) {
            c = rf.read();
            if (c == '\n' || c == '\r') {
              line = rf.readLine();
              if (line != null) {
                System.out.println(new String(line.getBytes("ISO-8859-1"), charset));
              }else {
                System.out.println(line);
              }
              nextend--;
            }
            nextend--;
            rf.seek(nextend);
            if (nextend == 0) {// 当文件指针退至文件开始处,输出第一行
              System.out.println(rf.readLine());
            }
          }
        } catch (FileNotFoundException e) {
          e.printStackTrace();
        } catch (IOException e) {
          e.printStackTrace();
        } finally {
          try {
            if (rf != null)
              rf.close();
          } catch (IOException e) {
            e.printStackTrace();
          }
        }
      }  public static void main(String args[]) {
        read("d:\\2.txt", "gbk");
      }
    }
      

  9.   

    最后几行是空行打印出null的情况已经解决:至于中文乱码的情况确实存在,我解决不了了,不知道哪位高手可指点一下
    package zipfile;import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.RandomAccessFile;public class FromEndRF {
    public static void main(String args[]){
    RandomAccessFile rf=null;
    try {
     rf=new RandomAccessFile("H:/JSP/tech/login.jsp","r");
    long len=rf.length();
    long start=rf.getFilePointer();
    long nextend=start+len-1;
    String line;
    rf.seek(nextend);
    int c=-1;
    while(nextend>start){
    c=rf.read();
    if(c=='\n'||c=='\r'){
    line=rf.readLine();
    if(line==null){//处理文件末尾是空行这种情况
    nextend--;
    rf.seek(nextend);
    continue;}
    System.out.println(line);
    nextend--;
    }
    nextend--;
    rf.seek(nextend);
    if(nextend==0){//当文件指针退至文件开始处,输出第一行
    System.out.println(rf.readLine());
    }
    }
    } catch (FileNotFoundException e) {
    e.printStackTrace();
    } catch (IOException e) {
    e.printStackTrace();
    }
    finally{
    try {
    rf.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    }
      

  10.   

    System.out.println(new String(line.getBytes("ISO-8859-1"), "GB2312"));System.out.println(new String(rf.readLine().getBytes("ISO-8859-1"), "GB2312"));把打印语句换成这个再试试看
      

  11.   

    上面的方法太麻烦拉,太傻了
    给个简单点的思路,是我刚刚在做的过程中想到的.
    直接一行行把读读到的内容放到一个list对象中.然后反着打印list里面的记录,不就可以了吗?
    这个方法是不是很好呢?做程序真的是写的好不如想的好,好的思路永远是最重要的
      

  12.   

    看到这位哥们的答案我笑了如果这个文件特别大都读到LIST里面。。然后再反过来读我擦这效率无法想象。。