I/O流体系

目录

一、字节流

1.InputStream

2.OutputStream

3.InputStream与OutputStream实现文件的拷贝

二、字符流

1.Reader

2.Writer

三、缓冲流

1.字节缓冲流

2.字符缓冲流

①BufferedReader

②BufferedWriter

四、转换流

1.使用字符输入转换流

2.使用UTF-8编码输出自己想要的GBK编码格式

五、序列化和反序列化

1.序列化

2.反序列化

六、打印流


IO流的作用?

读写文件数据的

IO流是怎么划分的,大体分为几类,各自的作用?

字节流:字节输入流,字节输出流(读写字节数数据的)

字符流:字符输入流,字符输出流(读写字符数据的)

一、字节流

1.InputStream

read()读取文件中的字节

public static void main(String[] args) throws Exception {
        InputStream input = new FileInputStream("src\\data.txt");
	int r;
	// read找不到下一位字节会返回-1
	while ((r = input.read()) != -1) {
         // 逐个读取,读取中文会乱码
         // UTF-8每个汉字占三个字节
		System.out.print((char) r);
	}
	System.out.println("\n===============================");                  

	InputStream input2 = new FileInputStream("src\\data.txt");
        //利用字节数组	
        byte[] buffer = new byte[3];
	int len;// 记录buffer的长度
	while ((len = input2.read(buffer)) != -1) {//读取中文也有可能乱码
		System.out.print(new String(buffer, 0, len));
	}
 }

 

当文件较小时可以定义为文件大小,一次性读取文件内容,可以避免乱码

    File f = new File("src\\data.txt");
    InputStream input3 = new FileInputStream(f);
    byte[] buffer1 = new byte[(int)f.length()];
    //也可以用
    //byte[] buffer1 = input3.readAllBytes();    
    //readAllbytes是JDK9出现的新方法
    input3.read(buffer1);
    System.out.print(new String(buffer1));

2.OutputStream

public static void main(String[] args) throws Exception {
		//OutputStream os = new FileOutputStream("src\\data.txt");//当创建出来时就会清空文件内的信息
		OutputStream os = new FileOutputStream("src\\data.txt", true);//在原有的数据上在末尾进行追加数据
		// 写一个字节
		os.write('q');
		os.write(97);
		// 写入字节数组
		byte[] buffer1 = { 'p', 97, 98, 32 };
		os.write(buffer1);
                os.write("\r\n".getBytes());//换行
		byte[] buffer2 = "我爱中国".getBytes();
		os.write(buffer2);
		
		os.flush();
		// 写入的数据再缓存区,需要进行刷新才能进入文件
		// 刷新后可以继续写入
		os.close();
		// 使用完需要关闭,释放资源
		// close()包括flush(),关闭后不能再进行写入

3.InputStream与OutputStream实现文件的拷贝

/*
 * 字节流适合一切文件的拷贝
 */
public static void main(String[] args) {
	InputStream is = null;
	OutputStream os = null;
	try {
		is = new FileInputStream("C:\\Users\\admin\\Desktop\\美女1.png");// 运行时文件路径可能报错,文件路径手动输入即可解决
		os = new FileOutputStream("C:\\Users\\admin\\Desktop\\美女2.png");
		byte[] buffer = new byte[1024];
		int len;
		while ((len = is.read(buffer)) != -1) {
			os.write(buffer, 0, len);
		}
		System.out.println("Success copy");
	} catch (IOException e) {
		e.printStackTrace();
	} finally {
		// 从内到外关闭
		try {
			if (os != null) {// 防止还没有创建OutputStream就出现异常
				os.close();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			if (is != null) {// 防止还没有创建InputStream就出现异常
				is.close();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

二、字符流

1.Reader

读取单个字符(包括汉字)

public static void main(String[] args) throws Exception {
        //每次读取一个字符
        //创建一个字符输入流管道
        Reader r = new FileReader("src/data.txt");
        int len;
        //每次读取一个字符返回,如果字节已经没有可读的返回-1
        while ((len = r.read()) != -1) {
            System.out.print((char) len);
        }      
    
}

使用字符数组读取一批字符

public static void main(String[] args) throws Exception {
        //创建一个字符输入流管道
        Reader r2 = new FileReader("src/data.txt");
        //每次读取1024字符
        char[] buffer = new char[1024];
        int len2;
        while ((len2 = r2.read(buffer)) != -1) {
        	System.out.print(new String(buffer, 0, len2));
        }
}

2.Writer

public static void main(String[] args) throws Exception {
	//创建一个管道
	//Writer wr = new FileWriter("src\\data.txt"); //创建时直接覆盖,没有追加
	Writer wr = new FileWriter("src\\data.txt",true);//使用时向后追加
	//写入单个字符
	wr.write("\r\n");//换行
	wr.write(97);
	wr.write('a');
	wr.write('嘿');
	wr.write("\r\n");//换行
        //写入字符数组
	char[] buffer = {'a','b','c','d'};
	wr.write(buffer);
 	//写入字符数组的一部分
	wr.write(buffer, 0, 3);
	//写入字符串
	wr.write("撸起袖子加油干!");
	//写入字符串的一部分
	wr.write("我爱你中国", 0, 3);
	//刷新
	wr.flush();
	//关闭,关闭也相当于刷新,关闭后不可以再进行写入
	wr.close();
 }

三、缓冲流

1.字节缓冲流

字节缓冲输入流:BufferedInputStream

字节缓冲输出流:BufferedOutputStream

可以提高InputStream和OutputStream的速度,BufferedInputStream和BufferedOutputStream自带8K的缓冲池。

public static void main(String[] args) {
	//使用try(管道建立){}catch(){}格式不用再进行手动关闭
	try (InputStream is = new FileInputStream("C:\\Users\\admin\\Desktop\\新建位图图像.bmp");
		OutputStream os = new FileOutputStream("C:\\Users\\admin\\Desktop\\新建位图图像2.bmp");
		// 建立输入流缓冲管道
		InputStream bis = new BufferedInputStream(is); 
		//建立输出流缓冲管道
		OutputStream bos = new BufferedOutputStream(os);) {
	        byte[] buffer = new byte[1024];
		int len;
		while ((len = bis.read(buffer)) != -1) {
			bos.write(buffer, 0, len);
		}
	        } catch (Exception e) {
		    e.printStackTrace();
		}
}

2.字符缓冲流

字符缓冲输入流:BufferedReader

字符缓冲输出流:BufferedWriter

可以提高Reader和Writer的速度,BufferedReader和BufferedWriter自带8K的缓冲池。

①BufferedReader

public static void main(String[] args) {
	try (Reader r = new FileReader("src\\data.txt"); BufferedReader br = new BufferedReader(r);) {
		// BufferedReader可以直接按行读取,当文件没有下一行时返回null
		String str;
		while ((str = br.readLine()) != null) {
			System.out.println(str);
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
}

②BufferedWriter

public static void main(String[] args) {
	//使用try(管道建立){}catch(){}格式不用再进行手动关闭
	try (InputStream is = new FileInputStream("C:\\Users\\admin\\Desktop\\新建位图图像.bmp");
		OutputStream os = new FileOutputStream("C:\\Users\\admin\\Desktop\\新建位图图像2.bmp");
		// 建立输入流缓冲管道
		InputStream bis = new BufferedInputStream(is); 
		//建立输出流缓冲管道
		OutputStream bos = new BufferedOutputStream(os);) {
        	byte[] buffer = new byte[1024];
        
        	int len;
    
		while ((len = bis.read(buffer)) != -1) {
			bos.write(buffer, 0, len);
		}
	  } catch (Exception e) {
		 e.printStackTrace();
        	}
}

四、转换流

用来解决文件与代码的编码格式不同(例:文件编码GBK,代码编码UTF-8)

1.使用字符输入转换流

可以提取文件(GBK)的原始字节流,原始字节不会存在问题。然后把字节流以指定编码转换成字符输入流,这样字符输入流中的字符就不乱码了

public static void main(String[] args) throws Exception {
	InputStream is = new FileInputStream("C:\\Users\\admin\\Desktop\\GBK编码格式.txt");
	// 将字节流转换为字符流
	Reader r = new InputStreamReader(is, "GBK");
	BufferedReader br = new BufferedReader(r);
	String str;
	while ((str = br.readLine()) != null) {
		System.out.println(str);
	}
	br.close();
 	r.close();
        is.close();
}

2.使用UTF-8编码输出自己想要的GBK编码格式

public static void main(String[] args) throws Exception {

	OutputStream os = new FileOutputStream("C:\\Users\\admin\\Desktop\\新建文本文档.txt");
	Writer w = new OutputStreamWriter(os,"GBK");
	BufferedWriter bw = new BufferedWriter(w);
	bw.write("我爱你中国");
	bw.newLine();
	bw.write("撸起袖子加油干");
	bw.close();
		
}

五、序列化和反序列化

序列化以及反序列化使用ObjectOutputStream和ObjectInputStream

1.序列化

public class ObjectOutputDemo {
	public static void main(String[] args) throws Exception {
		//序列化
		OutputStream is = new FileOutputStream("src\\student.txt");
		ObjectOutputStream oos = new ObjectOutputStream(is);
		student s = new student("1101","张三",18,180.5);
		oos.writeObject(s);
	}
}

2.反序列化

public class ObjectInputDemo {
	public static void main(String[] args) throws Exception{
		InputStream is = new FileInputStream("src\\student.txt");
		ObjectInputStream ois = new ObjectInputStream(is);
		student s = (student)ois.readObject();
		System.out.println(s);
	}
}

学生类

public class student implements Serializable {// 序列化必须实现Serializable接口
	private String id;
	private String name;
	private int age;
	private transient double height;// transient修饰时,序列化直接忽视这个属性

	public student() {
		super();
	}

	public student(String id, String name, int age, double height) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
		this.height = height;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public double getHeight() {
		return height;
	}

	public void setHeight(double height) {
		this.height = height;
	}

	@Override
	public String toString() {
		return "student [id=" + id + ", name=" + name + ", age=" + age + "]";
	}
}

六、打印流

作用:打印流可以实现方便、高效的打印数据到文件中去。打印流一般是指:PrintStream,Printwriter两个类。

打印流性能高效,方便写内容到文件中。打印功能上PrintStream和Printwriter没有区别

public static void main(String[] args) throws Exception{
	//打印流没法在文件末尾追加,如果想要追加,需要在低级流中定义追加
	PrintStream ps = new PrintStream(new FileOutputStream("src\\Print.txt",true));
	ps.println(97);
	ps.println('a');
	ps.println(true);
	ps.println("我在学Java");
	ps.close();
}

打印流重定向

public static void main(String[] args) throws Exception {
	System.out.println("我是第一句");
	PrintStream ps = new PrintStream(new FileOutputStream("src\\Print.txt",true));
	System.setOut(ps);//接下来的所有输出语句都会流入“src\\Print.txt”文件中
	System.out.println("我是第二句");
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值