笔试题目2-打印出文本文件的最后n行文本

 

# 打印出文本文件的最后 n行文本

请写出打印一个文本文件的最后 n行的程序。

## 要求
请正确处理 test-files 目录中的测试文件

## 编程要求:
考题时间是 45分钟

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * @author 
 * @version v1.0
 * @description 打印出文本文件的最后n行文本
 * @date 2020/1/13
 */
public class PrintLastLines {

    public static void main(String[] args) {

        final Path path = Paths.get("D:\\Exam\\test-files\\large.txt");
        RandomAccessFile randomAccessFile = null;
        int lineNumValue = 12;
        try {
            randomAccessFile = new RandomAccessFile(path.toFile(), "r");

//            positiveSequencePrint(randomAccessFile);

//            reversePrint(randomAccessFile);

//            reversePrint2(randomAccessFile);

//            reversePrintLastLines(randomAccessFile, lineNumValue);

            printLastLines(randomAccessFile, lineNumValue);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (randomAccessFile != null) {
                try {
                    randomAccessFile.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 正序打印文本最后几行
     * @param randomAccessFile
     * @param lineNumValue
     * @return
     * @throws IOException
     */
    private static void printLastLines(RandomAccessFile randomAccessFile, int lineNumValue) throws IOException {
        long length = randomAccessFile.length();
        if (length == 0L) {
            return;
        }
        long seekNext = length - 1;
        while (seekNext > 0 && lineNumValue > 0) {
            randomAccessFile.seek(seekNext);
            seekNext --;
            if (randomAccessFile.read() == '\n') {
                lineNumValue --;
            }
        }

        byte[] bytes = new byte[(int) (length - seekNext)];
        randomAccessFile.read(bytes);
        System.out.println(new String(bytes));
    }

    /**
     * 倒序打印出文本文件的最后n行文本
     * @param randomAccessFile
     * @param lineNumValue
     * @throws IOException
     */
    private static void reversePrintLastLines(RandomAccessFile randomAccessFile, int lineNumValue) throws IOException {
        long length = randomAccessFile.length();
        if (length == 0L) {
            return;
        }
        long seekNext = length - 1;
        randomAccessFile.seek(seekNext);

        int lineNum = 0;
        while (seekNext >= 0) {
            int read = randomAccessFile.read();
            //只有行与行之间才有\r\n,这表示读到每一行上一行的末尾的\n,而执行完read后,指针指到了这一行的开头字符
            if (read == '\n' && lineNum <= lineNumValue - 1) {
                //RandomAccessFile的readLine方法读取文本为ISO-8859-1,需要转化为windows默认编码gbk
                lineNum ++;
                printLine(randomAccessFile, lineNum);
            }
            // 当文件指针退至文件开始处,输出第一行
            if (seekNext == 0) {
                lineNum ++;
                randomAccessFile.seek(0);//不需要为下次做准备了,但是因为read()方法指针从0到了1,需重置为0

                if (lineNum <= lineNumValue - 1) {
                    printLine(randomAccessFile, lineNum);
                }
            } else {
                //为下一次循环做准备
                randomAccessFile.seek(seekNext - 1);
            }
            seekNext --;
        }
    }

    /**
     * 倒序打印方法二
     * @param randomAccessFile
     * @throws IOException
     */
    private static void reversePrint2(RandomAccessFile randomAccessFile) throws IOException {
        long length = randomAccessFile.length();
        if (length == 0L) {
            return;
        }
        long seekNext = length - 1;
        randomAccessFile.seek(seekNext);

        int lineNum = 0;
        while (seekNext >= 0) {
            int read = randomAccessFile.read();
            //只有行与行之间才有\r\n,这表示读到每一行上一行的末尾的\n,而执行完read后,指针指到了这一行的开头字符
            if (read == '\n') {
                //RandomAccessFile的readLine方法读取文本为ISO-8859-1,需要转化为windows默认编码gbk
                lineNum ++;
                printLine(randomAccessFile, lineNum);
            }
            // 当文件指针退至文件开始处,输出第一行
            if (seekNext == 0) {
                lineNum ++;
                randomAccessFile.seek(0);//不需要为下次做准备了,但是因为read()方法指针从0到了1,需重置为0
                printLine(randomAccessFile, lineNum);
            } else {
                //为下一次循环做准备
                randomAccessFile.seek(seekNext - 1);
            }
            seekNext --;
        }
    }

    /**
     * 倒序打印方法一
     * @param randomAccessFile
     * @throws IOException
     */
    private static void reversePrint(RandomAccessFile randomAccessFile) throws IOException {
        long length = randomAccessFile.length();
        if (length == 0L) {
            return;
        }
        long seekNext = length - 1;
        randomAccessFile.seek(seekNext);

        int lineNum = 0;
        while (seekNext >= 0) {
            int read = randomAccessFile.read();
            //只有行与行之间才有\r\n,这表示读到每一行上一行的末尾的\n,而执行完read后,指针指到了这一行的开头字符
            if (read == '\n') {
                //RandomAccessFile的readLine方法读取文本为ISO-8859-1,需要转化为windows默认编码gbk
                lineNum ++;
                printLine(randomAccessFile, lineNum);
            }
            //这一句必须在这个位置,如果在nextend--后,那么导致进0循环后去seek-1索引,报异常,如果在read()以前,那么导致进入0循环时,因为read指针到1,第一行少读取一个字符
            randomAccessFile.seek(seekNext);
            // 当文件指针退至文件开始处,输出第一行
            if (seekNext == 0) {
                lineNum ++;
                printLine(randomAccessFile, lineNum);
            }
            seekNext --;
        }
    }

    private static void printLine(RandomAccessFile randomAccessFile, int lineNum) throws IOException {
        String line = randomAccessFile.readLine();
        if (line == null || "".equals(line.trim())) {
            System.out.println(lineNum + "  " + (line == null ? "" : line));
        } else {
            System.out.println(lineNum + "  " + new String(line.getBytes(StandardCharsets.ISO_8859_1), "UTF-8"));
        }
    }

    /**
     * 正序打印所有行
     * @param randomAccessFile
     * @throws IOException
     */
    private static void positiveSequencePrint(RandomAccessFile randomAccessFile) throws IOException {
        String line;
        //行号
        int lineNum = 0;
        while ((line = randomAccessFile.readLine()) != null) {
            System.out.println(++lineNum + "  " + new String(line.getBytes(StandardCharsets.ISO_8859_1), "UTF-8"));
        }
    }
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值