【JAVA】文件操作(2)—文本文件行读取并显示字节和字符数

2021-11-25 00:00:00 字节 字符 文本文件

一、前言

本次学习应用于文本操作方面,前面我们说到实现文本的不同处理方式,本次目的是为了实现文件的各种操作

前面的博客中我们讲到了检测,新建,读取文件修改时间、大小和内容,并向指定文件写入指定内容。

这里我们学习文本文件行读取输出,并显示每行的字节和字符数

二、任务学习

任务要求:

  • 对文本文件按进行读取,每读取一行后显示此行。
  • 统计此行有多少字节并显示统计结果。
  • 统计此行有多少字符并显示统计结果。
  • 显示总的行数、字节数、字符数

1)分析学习:

《【JAVA】文件操作(2)—文本文件行读取并显示字节和字符数》

  • “字节”与“字符”

它们完全不是一个位面的概念,所以两者之间没有“区别”这个说法。不同编码里,字符和字节的对应关系不同:

①ASCII码中,一个英文字母(不分大小写)占一个字节的空间,一个中文汉字占两个字节的空间。一个二进制数字序列,在计算机中作为一个数字单元,一般为8位二进制数,换算为十进制。最小值0,最大值255。

UTF-8编码中,一个英文字符等于一个字节,一个中文(含繁体)等于三个字节。

③Unicode编码中,一个英文等于两个字节,一个中文(含繁体)等于两个字节。

符号:英文标点占一个字节,中文标点占两个字节。举例:英文句号“.”占1个字节的大小,中文句号“。”占2个字节的大小。

④UTF-16编码中,一个英文字母字符或一个汉字字符存储都需要2个字节(Unicode扩展区的一些汉字存储需要4个字节)。

⑤UTF-32编码中,世界上任何字符的存储都需要4个字节。

JAVA程序中会使用到的正则表达式

API中相关类:相关类位于:java.util.regex包下面
• 类 Pattern
– 正则表达式的编译表示形式。
Pattern p = Pattern.comp
ile(r,int); //建立正则表达式,并启用相应模式
• 类 Matcher
– 通过解释 Patterncharacter sequence 执行匹配操作的引擎
Matcher m = p.matcher(str); //匹配str字符串

2.在本次任务中实际会应用的语法:

(1)使用BufferedReader/BufferedWriter处理流和InputStreamReader/OutputStreamWriter处理流(IO流知识参见链接)

(2)判断数字:"\\d"

(3)判断字母:"[a-zA-Z]"

(4)判断汉字:"[\\u4e00-\\u9fa5]"

(5)判断空格:"\\s"

(6)判断标点:"\\pP"

(7)循环读取:.readLine()

每类字符查询分别调用方法,详情见下面程序。

2)程序代码:

/* 项目名称:Task_Du * 创建时间:2019年3月31日 * 创建者:Administrator_wz * 创建地点:kmust * 功能:按行读取并统计字节和字符数 */
 import java.io.*;//导入java.io包中的所有类
 import java.io.FileReader;//导入java.io包中的FileReader类
 import java.util.regex.Matcher;//导入java.util包中的Matcher类
 import java.util.regex.Pattern;//导入java.util包中的Pattern类
 import java.util.Scanner;//导入java.util包中的Scanner类
 import java.util.Date;//导入java.util包中的Date类
public class file5{ //创建类名
	public static void main(String[] args) throws IOException { //程序的主函数入口
		int n=0;             //字节数 
		int i=0;            //字符数 
		int line = 0;      //行数 
		int num = 0;      //数字数 
		int letter = 0;  //字母数 
		int space = 0;  //空格数 
		int word= 0;   //汉字数
		int punctuation= 0; //标点数
		long startTime=System.currentTimeMillis();//定义开始时间,用于统计程序的运行时长
		try{ //用try-catch语句将逻辑语句包起来,并读取指定的文件
        	Scanner s = new Scanner(System.in);//获取键盘输入并赋值给s字符串
        	System.out.println("请输入想要打开的文本文档:");//输入提示信息
        	String a = s.nextLine();//定义字符串变量,并赋值为用户输入的信息
			InputStreamReader read = new InputStreamReader(new FileInputStream(a),"utf-8"); //指定文件格式为utf-8
            BufferedReader br = new BufferedReader(read);//用于读取指定文件
			String str = null;//定义一个字符串类型变量str
			File file = new File(a);//定义待写入文件
			if(file.exists()){ //判断操作文件是否存在
				System.out.println("\n该文件已存在,无需创建!");//输出提示信息
				System.out.println("该文件最后的修改时间是:"+new Date(file.lastModified()));//输出文件的修改时间
				System.out.println("文本的内容为:\n");//输出提示信息
				while((str=br.readLine())!=null){ //readLine()方法, 用于读取一行,只要读取内容不为空就一直执行
					line++;//每循环一次就进行一次自增,用于统计文本行数
					num += countNumber(str);//用于统计文本当中的数字个数
					letter += countLetter(str);//用于统计文本中的字母个数
					word += countChinese(str);//用于统计文本当中的汉字个数
					punctuation += countPunctuation(str);//用于统计文本中的中文标点个数
					space += countSpace(str);//用于统计文本中的空格个数
					n=n+str.getBytes("UTF-8").length;//用于统计文本中的字节个数
					i=i+num+letter+word+punctuation+space;//用于统计文本中的字符个数
					System.out.println("第 " + line + " 行:" +str);//打印文本的内容 
					System.out.println("第 " + line + " 行有 " + str.getBytes("UTF-8").length + "个字节");//输出字节个数
					System.out.println("第 " + line + " 行有 " + (num+letter+word+punctuation+space) + "个字符");//输出字符个数
					num=letter=space=word=punctuation=0	;//归零
			}
			System.out.println("\n文本一共有 " + line + " 行");//打印文本行数
			}else{ //操作文件不存在
				file.createNewFile();//创建新文件夹
				System.out.println("\n该文件不存在,现已创建成功!");//输出提示信息
				System.out.println("该文件有共有"+file.length()+"字节");//输出文件字节数
				System.out.println("该文件最后的修改时间是:"+new Date(file.lastModified()));//输出文件的修改时间 
			}
		}catch(Exception e){ //当代码异常时用catch捕获异常
			e.printStackTrace();//printStackTrace()方法是打印异常信息在程序中出错的位置及原因
		}
		System.out.println("总字节数:"+ n );//输出文本的总字节数
		System.out.println("总字符数:"+ i );//输出文本的总字符数
		long endTime=System.currentTimeMillis();//定义一个结束时间
		long Time=endTime-startTime;//所需时间为结束时间-开始时间
		System.out.println("耗时:"+Time+"毫秒");//输出所用时间
	}
	/** * 统计数字数 * @param str * @return count */
	public static int countNumber(String str) { //创建countNumber方法用于统计文本的数字个数
        int count = 0;//创建一个返回值count
        Pattern p = Pattern.compile("\\d");//将给定的正则表达式编译并赋予给Pattern类 
        Matcher m = p.matcher(str);//生成一个给定命名的Matcher对象 
        while(m.find()){ //查找类似于Matcher对象的字符
            count++;//count自加作为标记
        }
        return count;//返回count值
    }
	/** * 统计字母数 * @param str * @return count */
    public static int countLetter(String str) { //创建countLetter方法用于统计文本的字母个数
        int count = 0;//创建一个返回值count
        Pattern p = Pattern.compile("[a-zA-Z]");//将给定的正则表达式编译并赋予给Pattern类 
        Matcher m = p.matcher(str);//生成一个给定命名的Matcher对象 
        while(m.find()){ //查找类似于Matcher对象的字符
            count++;//count自加作为标记
        }
        return count;//返回count值
    }
    /** * 统计汉字数 * @param str * @return count */
    public static int countChinese(String str) { //创建countChinese方法用于统计文本的汉字个数
        int count = 0;//创建一个返回值count
        Pattern p = Pattern.compile("[\\u4e00-\\u9fa5]");//将给定的正则表达式编译并赋予给Pattern类 
        Matcher m = p.matcher(str);//生成一个给定命名的Matcher对象 
        while(m.find()){ //查找类似于Matcher对象的字符
            count++;//count自加作为标记
        }
        return count;//返回count值
    }
    /** * 统计空格数 * @param str * @return count */
    public static int countSpace(String str) { //创建countSpace方法用于统计文本的空格个数
        int count = 0;//创建一个返回值count
        Pattern p = Pattern.compile("\\s");//将给定的正则表达式编译并赋予给Pattern类 
        Matcher m = p.matcher(str);//生成一个给定命名的Matcher对象 
        while(m.find()){ //查找类似于Matcher对象的字符
            count++;//count自加作为标记
        }
        return count;//返回count值
    }
	/** * 统计中文标点数 * @param str * @return count */
    public static int countPunctuation(String str) { //创建countPunctuation方法用于统计文本的标点个数
        int count = 0;//创建一个返回值count
        Pattern p = Pattern.compile("\\pP");//将给定的正则表达式编译并赋予给Pattern类 
        Matcher m = p.matcher(str);//生成一个给定命名的Matcher对象 
        while(m.find()){ //查找类似于Matcher对象的字符
            count++;//count自加作为标记
        }
        return count;//返回count值
    }
}

3)执行结果:

《【JAVA】文件操作(2)—文本文件行读取并显示字节和字符数》
《【JAVA】文件操作(2)—文本文件行读取并显示字节和字符数》

4)乱码原因及解决方法:

Java读取带有BOM的UTF-8格式txt文件第一行出现乱码——问号“?”及解决:
test.txt文件采用写字板保存为UTF-8格式
保存并关闭后使用写字板再次打开该UTF-8文档,中文、字母正常显示
《【JAVA】文件操作(2)—文本文件行读取并显示字节和字符数》

  • 解决办法:
    使用Notepad++等编辑器打开txt文件执行如下操作“格式–>以UTF-8无BOM格式编码”,修改后将txt文本进行保存,最终结果完好,无“?”出现。
    《【JAVA】文件操作(2)—文本文件行读取并显示字节和字符数》

参考链接:
https://blog.csdn.net/weixin_33712987/article/details/87112987
https://blog.csdn.net/milletguo/article/details/80144290
https://blog.csdn.net/u010889616/article/details/51477037
https://blog.csdn.net/mingzhuo_126/article/details/83512328
https://blog.csdn.net/iteye_15380/article/details/82438823
https://blog.csdn.net/major_zhang/article/details/73732743
https://blog.csdn.net/yangdan1025/article/details/86586863
https://blog.csdn.net/lyn1772671980/article/details/86691524
https://blog.csdn.net/andyzhaojianhui/article/details/53785656
https://blog.csdn.net/jackpk/article/details/5702964

    原文作者:王昭
    原文地址: https://blog.csdn.net/qq_42446456/article/details/88949416
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。

相关文章