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

一、前言

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

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

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

二、任务学习

任务要求:

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

1)分析学习:

在这里插入图片描述

  • “字节”与“字符”

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

①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)执行结果:

1
2

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

Java读取带有BOM的UTF-8格式txt文件第一行出现乱码——问号“?”及解决:
test.txt文件采用写字板保存为UTF-8格式
保存并关闭后使用写字板再次打开该UTF-8文档,中文、字母正常显示
1

  • 解决办法:
    使用Notepad++等编辑器打开txt文件执行如下操作“格式–>以UTF-8无BOM格式编码”,修改后将txt文本进行保存,最终结果完好,无“?”出现。
    在这里插入图片描述

参考链接:
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


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值