通过IO流解决统计字符和字符串出现次数的练习
练习1:统计一个文件calcCharNum.txt中字母’A’和’a’出现的总次数
package com.briup.day20;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* 统计一个文件calcCharNum.txt中字母'A'和'a'出现的总次数
* @author chouhan
* 1.遍历文本calcCharNum.txt中每一个字符
* 2.字符出现的次数存在Map中
* 3.把map中的数据写入文件a.txt中
*/
public class TimesTest {
public static void main(String[] args) {
//java.io.FileReader ,负责从文件中读取数据
FileReader fr=null;
//java.io.BufferedWriter,负责给字符输出流提供缓冲功能
BufferedWriter bw=null;
try {
//1.创建Map集合
Map<Character,Integer> map=new HashMap<Character,Integer>();
//2.遍历每一个字符,每一个字符出现的次数放到map中
fr=new FileReader("src/com/briup/day20/calcCharNum.txt");
int c=-1;
while((c=fr.read())!=-1) {
//int还原char
char ch=(char) c;
//判断char是否在map中第一次出现
if(map.get(ch)==null) {
map.put(ch,1);
}else {
map.put(ch, map.get(ch)+1);
}
}
//3.把map中数据存在文件a.txt中
//3.1.创建Writer
bw=new BufferedWriter(new FileWriter("src/com/briup/day20/a.txt"));
//3.2.遍历map,再写入数据
Set<Map.Entry<Character,Integer>> entrySet = map.entrySet();
for (Map.Entry<Character, Integer> entry : entrySet) {
switch (entry.getKey()) {
case 'A':
//把A=A的次数存入map集合中
bw.write("A="+entry.getValue());
break;
case 'a':
//把a=a的次数存入map集合中
bw.write("a="+entry.getValue());
break;
default:
//把其他字符和其对应个数也作为键值对存入map集合中
bw.write(entry.getKey()+"="+entry.getValue());
break;
}
bw.newLine();
}
}catch(Exception e) {
e.printStackTrace();
}finally {
//4.关闭流
if(fr!=null) {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bw!=null) {
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
练习2:写一个方法,输入一个文件名和一个字符串,统计这个字符串在这个文件中出现的次数。
package com.briup.day20;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
/**
* 写一个方法,输入一个文件名和一个字符串,统计这个字符串在这个文件中出现的次数。
* @author chouhan
* 查看jdk1.8的API:
* BufferedReader:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取。
* InputStreamReader:是从字节流到字符流的桥,它读取字节,并使用指定的charset将其解码为字符 。
* readLine:读一行文字。
* Reader:用于读取字符流的抽象类。
*/
public class TimesTest2 {
public static void main(String[] args) throws IOException {
//把"标准"输入流(键盘输入)这个字节流包装成字符流,再包装成缓冲流
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//调用readLine方法读取到输入的文件路径和字符串两行字符串
//因为try-catch的方法会导致输入的两个变量的作用范围只能在try代码块中,所以选择在主方法中抛出异常的方式
//但这样写没有对文件路径的进行其他处理,如果不输入正确的文件路径就会抛出文件找不到的异常:FileNotFoundException
System.out.println("请输入文件路径:");
String filePath = br.readLine();
System.out.println("请输入要统计的字符串:");
String msg = br.readLine();
//定义一个Reader类的in对象用于读取字符流
Reader in = null;
//字符串出现的次数,最后要输出,所以写在外面
int times = 0;
try {
for (int i = 0; i < msg.length(); i++) {
//因为InputStreamReader中的读取字符的方法不是读取一个就是读入数组,所以转了缓冲流再拿来比较
in = new FileReader(filePath);
char[] chars = new char[msg.length()];
br.skip(i);
int len = -1;
while ((len = in.read(chars)) != -1) {
String newStr = new String(chars, 0, len);
if (newStr.equals(msg)) {
times++;
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println(msg+"出现的次数为:"+times);
}
}