前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用IO流,在文本文件前增加行号

使用IO流,在文本文件前增加行号

作者头像
头发还在
发布2023-10-16 10:56:50
1590
发布2023-10-16 10:56:50
举报
文章被收录于专栏:桃花源

修改文本文件,在文件中每一行内容前增加行号,行号需要递增。

1、分析

读取文本文件,可以使用转换流 InputStreamReader 或者使用 FileReader;

写入文本文件,可以使用转换流 OutputStreamWriter 或者使用 FileWriter。

2、实现

2.1、字节流+转换流

即 InputStreamReader + OutputStreamWriter 。

因要在每行前增加行号,所以需要判断一行的开始或结束,所以我们需要了解行结束符的字节表达;

在windows机器上,行结束符为 \r\n,\n 作为一行的末尾字符,ASCII码转换为十进制就是10;

同时需要借助 StringBuilder 来临时存储当前行的内容,并把行号放到字符串的最前边,完成对行行号的写入操作。

代码语言:javascript
复制
import java.io.*;

public class AddLineNumber {
    public static void main(String[] args) {
        String ori = "d:/test.txt";

        new AddLineNumber().addLineNumber1(ori);
    }

    public void addLineNumber1(String ori){
        long start = System.currentTimeMillis();
        try(
                //文件读取
                InputStreamReader reader = new InputStreamReader(new FileInputStream(ori));
                //文件写入
                OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(ori + "1.txt"));
                ){
            int read = 0;
            int lineNumber = 1;
            StringBuilder temp = new StringBuilder();
            //格式化输出,行号为两位数字,不足两位时前边补0
            temp.append(String.format("%02d ", lineNumber));
            while ((read = reader.read()) != -1){

                //判断是否一行的结束,windows中结束符为 \r\n; \n的字节为 10
                if(read != 10){
                    temp.append((char) read);
                }else {
                    //按行更新到文件中
                    temp.append((char) read);
                    writer.write(temp.toString());
                    writer.flush();
                    //重置 StringBuilder
                    temp.setLength(0);
                    temp.append(String.format("%02d ", ++lineNumber));
                }
            }

            //因最后一行可能没有换行符,需要在这里单独处理
            if(temp.length() > 0){
                writer.write(temp.toString());
                writer.flush();
                temp.setLength(0);
            }

            long end = System.currentTimeMillis();

            System.out.println(end - start);
        }catch (Exception e){
            e.printStackTrace();
        }

    }
}

注: 1、代码中没有写关闭流的语句,因为使用了 try...catch...resource 语法糖,由JVM执行关闭流的操作。 2、行号写入时,使用的字符串格式化,String.format("%02d ", lineNumber),表示使用两位数字来表示行号,如果不足两位时,前边补充0。

2.2、字符缓冲流+转换流

通过观察代码,可以发现只使用转换流和字节流,代码冗余,也不易理解,需要进行优化。

下边将通过使用字符缓冲流按行读取文本内容,增加行号后再按行写入。

代码语言:javascript
复制
import java.io.*;

public class AddLineNumber {
    public static void main(String[] args) {
        String ori = "d:/test.txt";

        new AddLineNumber().addLineNumber2(ori);
    }

    public void addLineNumber2(String ori){
        long start = System.currentTimeMillis();
        try(
                //文件读取
                InputStreamReader reader = new InputStreamReader(new FileInputStream(ori));
                BufferedReader br = new BufferedReader(reader);
                //文件写入
                OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(ori + "2.txt"));
                BufferedWriter bw = new BufferedWriter(writer);
        ){
            String read = "";
            int lineNumber = 1;
            while ((read = br.readLine()) != null){
                bw.write(String.format("%02d %s", lineNumber++, read));
                bw.newLine();
            }

            bw.flush();
            long end = System.currentTimeMillis();

            System.out.println(end - start);
        }catch (Exception e){
            e.printStackTrace();
        }

    }
}

注:

BufferedWriter 中的 newLine() 方法,其实就是在每行的最后加上换行符,可以不用写这句,直接在字符串的格式化末尾加上换行符 \r\n 即可,如

代码语言:javascript
复制
bw.write(String.format("%02d %s\r\n", lineNumber++, read));

2.3 字符流+字符缓冲流

相比2.1中的代码,2.2的代码相对简洁,但其实是读取文本文件,完全可以使用 Reader 和 Writer 来实现。

代码语言:javascript
复制
import java.io.*;

public class AddLineNumber {
    public static void main(String[] args) {
        String ori = "d:/test.txt";

        new AddLineNumber().addLineNumber3(ori);
    }

    public void addLineNumber3(String ori){
        long start = System.currentTimeMillis();
        try(
                //文件读取
                BufferedReader br = new BufferedReader(new FileReader(ori));
                //文件写入
                PrintWriter pw = new PrintWriter(ori + "4.txt");
        ){
            String read = "";
            int lineNumber = 1;
            while ((read = br.readLine()) != null){
                pw.println(String.format("%02d %s", lineNumber++, read));
            }

            pw.flush();
            long end = System.currentTimeMillis();

            System.out.println(end - start);
        }catch (Exception e){
            e.printStackTrace();
        }

    }
}

可以看到,在写入文件时,只创建了一个 PrintWriter 对象,不需要再使用其它处理流,这种实现方式,代码看起来最为简洁,给人一种清爽的感觉。

3、结果展示

最后来看一下源文件和修改后文件的区别吧

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-02-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、分析
  • 2、实现
    • 2.1、字节流+转换流
      • 2.2、字符缓冲流+转换流
        • 2.3 字符流+字符缓冲流
        • 3、结果展示
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档