IO
文件
文件就是我们保存数据的地方。
-
文件流
文件在程序中是以流的形式来操作的
-
流:数据在数据源(文件)和程序(内存)之间经历的路径
-
输入流:数据从数据源(文件)到程序(内存)的路径
-
输出流:数据从程序(内存)到数据源(文件)的路径
创建文件
-
new File(String path)
// new File(String path) @Test public void creatFile1() { File file = new File("e:\\news1.txt"); try { file.createNewFile(); System.out.println("创建成功"); } catch (IOException e) { e.printStackTrace(); } }
-
new File(File parent, String child)
// new File(File parent, String child) @Test public void createFile2() { File parent = new File("e:\\"); String child = "news2.txt"; File file = new File(parent, child); try { file.createNewFile(); System.out.println("创建成功"); } catch (IOException e) { e.printStackTrace(); } }
-
new File(String parent, String child)
//new File(String parent, String child) @Test public void createFile3() { //String parent = "e:\\"; String parent = "e:/"; String child = "news4.txt"; File file = new File(parent, child); try { file.createNewFile(); System.out.println("创建成功"); } catch (IOException e) { e.printStackTrace(); } }
文件信息
// getName length getParent getAbsolutePath exists isFile isDirectory
@Test
public void fileInfo() {
File file = new File("e:\\news1.txt");
System.out.println("文件名:" + file.getName());
System.out.println("文件大小:" + file.length());
System.out.println("文件父目录:" + file.getParent());
System.out.println("文件绝对路径:" + file.getAbsolutePath());
System.out.println(file.getAbsoluteFile());
System.out.println("文件是否存在:" + file.exists()); // true
System.out.println("是否是文件:" + file.isFile()); // true
System.out.println("是否是目录:" + file.isDirectory()); // false
}
目录操作和文件删除
// 判断 e:\news1.txt 是否存在,若存在就删除
@Test
public void m1() {
File file = new File("e:\\news1.txt");
if(file.exists()) {
if(file.delete()) {
System.out.println(file.getName() + "删除成功");
}else{
System.out.println(file.getName() + "删除失败");
}
}else{
System.out.println(file.getName() + "不存在");
}
}
// 判断: d:\\demo02 是否存在,存在删除,不存在给出提示
@Test
public void m2() {
File file = new File("e:\\demo02");
if(file.exists()) {
if(file.delete()) {
System.out.println(file.getName() + "删除成功");
}else{
System.out.println(file.getName() + "删除失败");
}
}else{
System.out.println(file.getName() + "不存在");
//if(file.mkdirs()) { // 创建一级或多级目录
if(file.mkdir()) { // 创建一级目录
System.out.println(file.getAbsolutePath() + "文件/目录已创建");
}
}
}
// 判断: d:\\demo02\\a\\b\\c 目录是否存在,若存在就提示存在,否则创建
@Test
public void m3() {
File file = new File("e:\\demo02\\a\\b\\c");
if(file.exists()) {
System.out.println(file.getAbsolutePath() + "目录已存在");
}else{
if(file.mkdirs()) {
System.out.println(file.getAbsolutePath() + "目录创建成功");
}else{
System.out.println(file.getAbsolutePath() + "目录创建失败");
}
}
}
IO流原理及流的分类
java IO流原理
- I/O是Input/Output的缩写,I/O技术是非常实用的技术,用于处理数据传输。如读写文件,网络通讯等。
- java程序中,对于数据的输入/输出操作以“流(Stream)”的方式进行
- java.io包下提供各种“流”类和接口,用于以获取不同种类的数据,并通过方法输入或输出数据。
- 输入流:读取外部文件到程序(内存)中
- 输出流:将程序(内存)中的数据输出到磁盘,光盘等存储设备中
流的分类
- 按操作数据单位分为:字节流(8 bit)处理任何文件,包括二进制文件、字符流,只能处理文本文件
- 按数据流向分:输入流、输出流
- 按流的角色分:节点流、处理流/包装流
抽象类 | 字节流 | 字符流 |
---|---|---|
输入流 | InputStream | Reader |
输出流 | OutputStream | Writer |
java的io类共涉及40多个类,实际上非常规则,都是从以上4个抽象基类派生的
有这4个派生出来的子类名称都是以其父类名作为子类名后缀。
节点流和处理流
节点流可以从一个特定的数据源读写数据,如FileReader,FileWriter[源码]
处理流(也叫包装流)是“连接”在已存在的流(节点流或处理流之上的),为程序提供更为强大的读写功能,如BufferedReader、BufferedWriter[源码]
节点流和处理流的区别和联系
- 节点流是底层流和低级流,直接与数据源相联
- 处理流(包装流)是包装节点流,既可以消除不同节点流的实现差异,也可以提供给更方便的方法来完成输入输出。
- 处理流i(也叫包装流)对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相联
处理流功能:
- 性能的提高:主要以增加缓冲的方式来提供输入输出的效率
- 操作的便捷:处理流可能提供了一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活。
修饰器demo
public abstract class Reader_ {
public void readFile() {};
public void readString(){};
}
public class StringReader_ extends Reader_ {
@Override
public void readString() {
System.out.println("读取字符串~");
}
}
public class FileString_ extends StringReader_ {
@Override
public void readFile() {
System.out.println("读取文件内容");
}
}
public class BufferedReader_ {
private Reader_ reader_;
public BufferedReader_(Reader_ reader) {
this.reader_ = reader;
}
public void readFile() {
this.reader_.readFile();
}
public void readString() {
this.reader_.readString();
}
public void readFiles(int num) {
for (int i = 0; i < num; i++) {
this.reader_.readFile();
}
}
public void readStrings(int num) {
for (int i = 0; i < num; i++) {
this.reader_.readString();
}
}
}
测试
@Test
public void testReadString() {
BufferedReader_ reader_ = new BufferedReader_(new StringReader_());
reader_.readString();
System.out.println("-----");
reader_.readStrings(5);
}
@Test
public void testReadFile() {
BufferedReader_ reader_ = new BufferedReader_(new FileString_());
reader_.readFile();
System.out.println("-----");
reader_.readFiles(5);
}
输入流
InputStream字节输入流,是抽象类,是所有类字节输入流的超类
-
read()
@Test public void read01() { FileInputStream fileInputStream = null; try { fileInputStream = new FileInputStream("e:\\hello.txt"); int data; // read方法 一次读取一个字节 // 数据的下一个字节,如果达到文件的末尾, -1 。 while((data = fileInputStream.read()) != -1) { System.out.print((char)data); } } catch (IOException e) { e.printStackTrace(); } finally { try { fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } }
-
read(byte[] b)
@Test public void read02() { FileInputStream fileInputStream = null; try { fileInputStream = new FileInputStream("e:\\hello.txt"); byte[] buf = new byte[8]; int readLength = 0; while((readLength = fileInputStream.read(buf)) != -1) { System.out.print(new String(buf, 0, readLength)); } } catch (IOException e) { e.printStackTrace(); } finally { try { fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } }
输出流
OutputStream字节输出流,是抽象类,是所有类字节输出流的超类
@Test
public void write01() {
String filePath = "e://hello.txt";
FileOutputStream fileOutputStream = null;
try {
// 创建输出流 默认覆盖原数据
//fileOutputStream = new FileOutputStream(filePath);
// 创建输出流,指定是否追加 true则在文件末尾追加
fileOutputStream = new FileOutputStream(filePath,true);
//fileOutputStream.write('H');
String str = "Hello JAVA ~ IO ~ OutputStream";
//fileOutputStream.write(str.getBytes());
fileOutputStream.write(str.getBytes(),0,str.length());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
字符流
FileReader和FileWriter
FileReader和FileWriter是字符流,按照字符来操作IO
- new FileReader(File/String)
- read:每次读取单个字符,返回该字符,如果到文件末尾返回-1
- read(char[]):批量读取多个字符到数组,返回读取到的字符数,如果到文件末尾返回-1
- 相关API:
- new String(char[]) 将char[]转换成数组
- new String(char[],off,len): 将char[]的指定部分转换成String
/**
* 读取文件 单个字符读取
*/
@Test
public void fileRead01() {
String filePath = "e:\\story.txt";
try {
FileReader fileReader = new FileReader(filePath);
int readContent = 0;
while((readContent = fileReader.read()) != -1) {
System.out.print((char) readContent);
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 读取文件 字符数组读取
*/
@Test
public void fileRead02() {
String filePath = "e:\\story.txt";
try {
System.out.println("~~~读取文件 字符数组读取~~~");
FileReader fileReader = new FileReader(filePath);
int readlength = 0;
char[] buf = new char[16];
while((readlength = fileReader.read(buf)) != -1) {
System.out.print(new String(buf,0,readlength));
}
} catch (IOException e) {
e.printStackTrace();
}
}
FileWriter常用方法
- new FileWriter(File/String) 覆盖模式,默认流的指针在首端
- new FileWriter(File/String,true),追加模式,相当于流的指针在尾端
- Writer(int) 写入单个字符
- Write(char[]) 写入指定数组
- write(char,off,len) 写入指定数组的指定部分
- write(String) 写入整个字符串
- write(String,off,len): 写入字符串的指定部分
相关API:String类,tocharArray,将String转换成 char[]
注意:FileWriter使用后,必须关闭(close)或刷新(flush),否则写入不到指定文件
@Test
public void write() {
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter("e:\\note.txt");
// 添加单个字符
fileWriter.write("H");
// 添加字符数组
fileWriter.write("Hello java IO-FileWriter".toCharArray());
// 添加字符数组指定内容
fileWriter.write(" Hello java IO-FileWriter".toCharArray(), 0, 5);
// 添加字符串
fileWriter.write(" Hello java");
// 添加字符串指定内容
fileWriter.write(" Hello java", 0, 6);
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(fileWriter != null) {
// 注意:必须书写 close 或 flush 方法
// 因为该方法中调用了写出内容的方法 fileoutStream.writeBytes
fileWriter.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("结束");
}
缓冲字符流
BufferedReader和BufferedWriter
bufferedReader和BufferedWriter属于字符流,是按照字符来读取数据的
关闭时,只需要关闭外层流即可。
public static void main(String[] args) throws IOException {
String filePath = "e:\\story.txt";
BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
String line = "";
while((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
// 关闭流 关闭最外层即可
// 源码关闭的还是fileReader的流
bufferedReader.close();
}
bufferedWriter
public static void main(String[] args) throws IOException {
String filePath = "e:\\hello.txt";
// new FileWriter(filePath,true) 追加模式
// new FileWriter(filePath) 覆盖模式
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath,true));
bufferedWriter.write("你好,java缓冲字符流");
bufferedWriter.newLine(); // 换行符 与当前系统有关系
bufferedWriter.write("你好2,java缓冲字符流");
bufferedWriter.newLine(); // 换行符 与当前系统有关系
bufferedWriter.write("你好3,java缓冲字符流");
bufferedWriter.close();
}
文件拷贝
@Test
public void copyFile() {
// 注意:缓冲流 只能操作字符,不能操作二进制文件
// 即不能读取 视频 音频 图片 doc pdf
String srcFilePath = "e:\\story.txt";
String destFilePath = "e:\\story2.txt";
BufferedWriter bufferedWriter = null;
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new FileReader(srcFilePath));
bufferedWriter = new BufferedWriter(new FileWriter(destFilePath));
String line;
while ( (line = bufferedReader.readLine()) != null) {
bufferedWriter.write(line);
bufferedWriter.newLine(); // 此处进行换行
}
System.out.println("拷贝结束");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(bufferedReader != null) {
bufferedReader.close();
}
if(bufferedWriter != null) {
bufferedWriter.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
缓冲字节流
BufferedInputStream 和BufferedOutputStream
BufferedInputStream之字节流,在创建BufferedInputStream时,会创建一个内部缓冲数组。
BufferedOutputStream是字节流,实现缓冲的输出流,可以将多个字节写入底层输出流中,而不必对每次字节写入调用底层系统
@Test
public void copyFile2() {
String srcFilePath = "e:\\谷歌插件.png";
String destFilePath = "e:\\谷歌插件图片.png";
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream(srcFilePath));
bos = new BufferedOutputStream(new FileOutputStream(destFilePath));
byte[] buff = new byte[1024];
int readLength;
while((readLength = bis.read(buff)) != -1) {
bos.write(buff,0,readLength);
}
System.out.println("拷贝完成~");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(bis != null) {
bis.close();
}
if(bos != null) {
bos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
对象流
ObjectInputStream和ObjectOutputStream
objectInputStream和ObjectOutputStream 对象流
保存对象时,需要进行序列化,恢复对象时,需要反序列化。
序列化:在保存数据时,保存数据的值和类型,如保存 new dog(“小黄”,3);
反序列化:恢复数据时,恢复数据的值和类型
某个类支持序列化需要实现Serializable和Externalizable两个接口中一个。
package com.hopeful.outputstream_;
import java.io.Serializable;
/**
* Dog
*/
public class Dog implements Serializable {
public String name;
public int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public static void main(String[] args) throws IOException {
String filePath = "e:\\data.data";
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
oos.writeInt(100);
oos.writeChar('A');
oos.writeBoolean(true);
Dog dog = new Dog("旺财", 2);
oos.writeObject(dog);
System.out.println("序列化完成~");
oos.close();
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
String filePath = "e:\\data.data";
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
System.out.println(ois.readInt());
System.out.println(ois.readChar());
System.out.println(ois.readBoolean());
Dog dog = (Dog) ois.readObject();
System.out.println(dog);
ois.close(); // 关闭流
}
注意事项
- 读写顺序要一致
- 要求实现序列化和反序列化对象,需要实现 Serializable
- 序列化类中建议添加 SerialVersionUID,为了提高版本的兼容性
- 序列化对象时,默认将里面所有属性都进行序列化,但除了static或transient修饰的成员
- 序列化对象时,要求里面的属性类型也需要实现序列化接口
- 序列化具有可继承性,也就是某类实现了可序列化,则他的子类也默认实现了序列化
标准输入输出流
类型 | 默认设备 | |
---|---|---|
System.in | InputStream | 键盘 |
System.out | PrintStream | 显示器 |
public static void main(String[] args) {
// System 类的 public final static InputStream in = null;
// 编译类型:InputStream
// 运行类型:BufferedInputStream
// 表示标准输入 键盘
InputStream in = System.in;
// System 类的 public final static PrintStream out = null;
// 编译类型:PrintStream
// 运行类型:PrintStream
// 表示标准输出 显示器
PrintStream out = System.out;
Scanner scanner = new Scanner(System.in);
String next = scanner.next();
System.out.println("Hello 标准输入输出: " + next);
}
转换流
转换流:InputStreamReader和OutputStreamWriter
- InputStreamReader:Reader的子类,可以将InputStream(字节流)包装成Reader(字符流)
- OutputStreamWriter:Writer的子类,实现将OutputStream(字节流)包装成Writer(字符流)
- 当处理纯文本数据时,如果使用字符流效率更高,并且可以有效解决中文乱码问题,所以建议将字节流转换成字符流
- 可以指定编码格式(比如utf-8,gbk,gb2312,iso8859-1)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uH0yhk3J-1664181931556)(IO.assets/image-20220925161600820.png)]
编码问题:字符编码为utf-8 显示正常
public static void main(String[] args) throws IOException {
// 1.获取BufferedReader字符对象
String filePath = "e:\\story2.txt";
BufferedReader bos = new BufferedReader(new FileReader(filePath));
String lineContent;
// 读取文本
while((lineContent = bos.readLine()) != null) {
// 字符编码为utf-8 显示正常
// 其他编码 读取乱码
System.out.println(lineContent);
}
bos.close();
System.out.println("读取结束~~");
}
使用转换流解决乱码问题:
public static void main(String[] args) throws IOException {
String filePath = "e:\\story2.txt";
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath),"gbk"));
String lienContent;
while((lienContent = br.readLine()) != null) {
System.out.println(lienContent);
}
br.close();
System.out.println("读取结束");
}
public static void main(String[] args) throws IOException {
String filePath = "e:\\hello.txt";
// 编码格式 utf-8/utf8 都可以
String charset = "utf8";
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath), charset));
bw.write("hello, 世界");
bw.close();
}
打印流
打印流:PrintStream和PrintWriter,只要输出流,没有输入流
public static void main(String[] args) throws IOException {
PrintStream out = System.out;
// 默认输出位置是控制台
out.println("Hello IO");
// print方法 底层调用的就是write方法
out.write("你好 输入输出".getBytes());
out.close();
// 修改输出位置
String filePath = "e:\\print.txt";
System.setOut(new PrintStream(filePath));
// 输出内容
System.out.println("修改位置输出内容");
}
public static void main(String[] args) throws IOException {
PrintWriter pw = new PrintWriter(new FileWriter("e:\\story3.txt"));
pw.write("你好哇");
pw.close();
pw.close();
}
properties类
src下添加mysql.properties配置文件
ip=192.168.0.1
user=root
pwd=12345
常规写法
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("src\\mysql.properties"));
String lineContent;
while((lineContent = br.readLine()) != null) {
String[] arr = lineContent.split("=");
System.out.println(arr[0] + "值是" + arr[1]);
}
br.close();
}
properties写法
public static void main(String[] args) throws IOException {
// 创建Properties对象
Properties properties = new Properties();
// 加载文件
properties.load(new FileReader("src\\mysql.properties"));
properties.list(System.out);
// 获取指定属性的值
String user = properties.getProperty("user");
String pwd = properties.getProperty("pwd");
System.out.println("用户名:" + user + ",密码:" + pwd);
// 设置属性
// 如果有key,修改
// 若无key,则创建
// Properties 父类是hashTable 底层就是HashTable
properties.setProperty("user","root");
properties.setProperty("addr","河南郑州");
properties.store(new FileWriter("src\\mysql2.properties"),null);
}
练习题
创建文件夹及文件
// e盘下不存在mytemp目录,就创建
// 在mytemp目录下,创建hello.txt
// 如果hello.txt 已存在,提示文件已存在,不要重复创建了
@Test
public void test1() throws IOException {
String dirPath = "e:\\mytemp";
File dir = new File(dirPath);
if(!dir.exists()) {
if(dir.mkdir()) {
System.out.println("目录创建成功");
}else{
System.out.println("目录创建失败");
}
}
File file = new File(dirPath + "\\hello.txt");
if(!file.exists()) {
if(file.createNewFile()) {
System.out.println("文件创建完成~");
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "utf8"));
bw.write("Hello java-io");
bw.close();
}else{
System.out.println("文件创建失败");
}
}else{
System.out.println("文件已存在,请勿重复创建");
}
}
为读取的每行信息添加行号
/**
* 使用BufferedReader 读取一个文本文件,为每行添加行号
* 再连同内容一起输出屏幕
*/
@Test
public void test02() throws IOException {
String filePath = "e:\\story2.txt";
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath),"gbk"));
String lineContent;
int i = 0;
while((lineContent = br.readLine()) != null) {
System.out.println(++i + lineContent);
}
br.close();
System.out.println("文件读取完毕~");
}
读取配置文件,创建对象,序列化对象至文件,反序列化对象信息
class Dog2 implements Serializable {
private String name;
private int age;
private String color;
public Dog2(String name, int age, String color) {
this.name = name;
this.age = age;
this.color = color;
}
@Override
public String toString() {
return "Dog2{" +
"name='" + name + '\'' +
", age=" + age +
", color='" + color + '\'' +
'}';
}
}
/**
* 编写 dog.properties
* name=tom
* age=5
* color=red
* 编写Dog类(name,age,color)创建dog对象,读取dog.properties用相应内容初始化
* 将创建的dog对象,序列化到dog.dat文件
*/
@Test
public void test03() throws IOException, ClassNotFoundException {
Properties properties = new Properties();
properties.load(new FileInputStream("src\\dog.properties"));
properties.list(System.out);
String name = properties.getProperty("name");
String age = properties.getProperty("age");
String color = properties.getProperty("color");
Dog2 dog = new Dog2(name, Integer.parseInt(age), color);
System.out.println(dog);
// 序列化对象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("e:\\data.dat"));
oos.writeObject(dog);
oos.close();
// 反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("e:\\data.dat"));
Object object = ois.readObject();
System.out.println("反序列化---");
System.out.println(object);
ois.close();
}
文件或目录递归删除
/**
* 使用File类删除某个文件夹(例如D盘下的temp文件夹)下的所有文件和文件夹:
* * 1) 判断temp文件夹下的文件类型,如果是文件则直接删除
* * 2) 如果是文件夹则获取该文件夹下的子文件和文件夹
* * 3) 使用递归的方式删除所有temp文件夹下的文件和文件夹
*/
@Test
public void test03() {
String dirPath = "e:\\demo";
File dir = new File(dirPath);
judge(dir); // 判断遍历文件
deleteFileAndDir(dir); // 删除文件或目录
}
public static void judge(File dir) {
if(dir.exists()) {
File[] files = dir.listFiles();
for (File f : files) {
if(f.isDirectory()) {
System.out.println("遍历目录"+f.getName());
judge(f);
}else{
System.out.println(f.getName());
}
}
}
}
public static void deleteFileAndDir(File dir) {
if(dir.exists()) {
File[] files = dir.listFiles();
for (File file : files) {
if(file.isFile()) {
file.delete();
System.out.println(file.getName()+"已删除");
}else{
deleteFileAndDir(file);
}
}
dir.delete();
}else{
System.out.println("目录或文件不存在");
}
}
查看指定后缀名的文件
ublic static void judge2(File dir,String suffix) {
if(dir.exists()) {
File[] files = dir.listFiles();
for (File file : files) {
if(file.isFile()) {
String name = file.getName();
if(suffix != null && suffix.equals(name.substring(name.lastIndexOf(".") + 1))) {
System.out.println(name);
}
}else if(file.isDirectory()) { // 目录
judge2(file,suffix);
}
}
}else{
System.out.println("目录或文件不存在");
}
}
/**
* 递归实现列出当前工程下所有.java文件
*/
@Test
public void test09() {
File file = new File("src\\");
judge2(file,"java");
}
统计文本中字符的个数
/**
*统计一个文件calcCharNum.txt(见附件)中各个字母出现次数:
*
* A(8),B(16),C(10)...,a(12),b(10),c(3)....,括号内代表字符出现次数;
*/
@Test
public void test10() throws IOException {
File file = new File("e:\\calcCharNum.txt");
BufferedReader br = new BufferedReader(new FileReader(file));
int len;
HashMap<Character, Integer> map = new HashMap<>();
while((len = br.read()) != -1) {
Set<Character> characters = map.keySet();
if(characters.contains((char)len)) {
map.put((char)len, map.get((char)len) + 1);
}else{
map.put((char)len, 1);
}
}
br.close();
Set<Character> characters = map.keySet();
for (Character character : characters) {
System.out.print(character + ":" + map.get(character) + " ");
}
}
IO常用类分类
分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
---|---|---|---|---|
抽象基类 | InputStream | OutputStream | Reader | Writer |
访问文件 | FileInputStream | FileOutputStream | FileReader | FileWriter |
访问数组 | ByteArrayInputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter |
访问管道 | PipedInputStream | PipedOutputStream | PipedReader | PipedWriter |
访问字符串 | StringReader | StringWriter | ||
缓冲流 | BufferedInputStream | BufferedOutputStream | BufferedReader | BufferedWriter |
转换流 | InputStreamReader | OutputStreamWriter | ||
对象流 | ObjectInputStream | ObjectOutputStream |
抽象基类 | FilterInputStream | FilterOutputStream | FilterReader | FilterWriter |
---|---|---|---|---|
打印流 | PrintStream | PrintWriter | ||
退回输入流 | PushBackInputStream | PushBackReader | ||
特殊流 | DataInputStream | DataOutputStream |