IO流应用:在文本文件前增加行号

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IO流应用:在文本文件前增加行号相关的知识,希望对你有一定的参考价值。

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

0、需求

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

1、分析

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

写入文本文件,可以使用转换流 ​​OutputStreamWriter​​ 或者使用 ​​FileWriter​​。 在写入行号时,增加一个字符串的格式化操作,行号使用两位数字表示,当不足两位时,前边补0。

2、实现

2.1、字节流+转换流

即​​InputStreamReader​​ + ​​OutputStreamWriter​​。

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

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

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

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、字符缓冲流+转换流

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

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

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 即可,如

​bw.write(String.format("%02d %s\\r\\n", lineNumber++, read));​

2.3 字符流+字符缓冲流

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

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、结果展示

最后来看一下实现的效果吧

IO流应用:在文本文件前增加行号_文本文件

以上是关于IO流应用:在文本文件前增加行号的主要内容,如果未能解决你的问题,请参考以下文章

JAVA IO流复制文件内容

使用java的输入输出流将一个文本文件的内容按行读取,每读一行就顺序添加行号,并写入到另一个文件中

VIM文本编辑器

java 中简述使用流进行读写文本文件的步骤?

Java IO流-合并流

Java学习之IO流(序列流--SequenceInputStream)