IO流-字符流、字节流等

文章的许多内容来源于:
- https://blog.csdn.net/Chianz632/article/details/79946851
- https://blog.csdn.net/jediael_lu/article/details/26813153
- https://www.cnblogs.com/liyanyan665/p/11198605.html

JAVA中可以分为两种流:字节流和字符流。如果细分的话有,可分为:4个文件流,4个缓冲流,2个转换流,2个打印流,2个序列化流,2个数据流。

文件流
FileInputStream //字节输入流
FileOutputStream //字节输出流
FileReader //字符输入流
FileWriter //字符输出流

缓冲流
BufferedInputStream //字节输入缓冲流
BufferedOutputStream //字节输出缓冲流
BufferedReader //字符输入缓冲流
BufferedWriter //字符输出缓冲流

序列化流
ObjectInputStream
ObjectOutputStream

转换流(字符流) 将字节流转换为字符流
InputStreamReader
OutputStreamWriter

数据流
DataInputStream
DataOutputStream

打印流
PrintWriter
PrintStream

本文只讲文件流和序列化流的使用

一、字节流FileInputStream 和FileOutputStream

有人可能会好奇,为什么存储文件时用Output,而读取文件却时Input呢,其实这里的存储和读取时相对一内存而言的。
FileOutputStream: 将内存中的数据存储到硬盘中。 所以是Output
FileInputStream: 读取硬盘中的数据到内存中,所以是Input

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;

public class Test {
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		Scanner reader = new Scanner(System.in);  //从控制台读取
		
		//写文件
		File file=new File("wenjian.txt"); //文件名
		FileOutputStream fos =new FileOutputStream(file,true);  //true意思是 追加存储
		System.out.println("请输入要写入的内容:");
		String message=reader.next();  //从控制台读取字符
		byte bytes[]=message.getBytes();
		fos.write(bytes,0,bytes.length); //存入
		
		fos.close(); //关闭流System
		System.out.println("文件写入成功!");
		
		
		//读文件
		FileInputStream fis=new FileInputStream(file);
		byte b[]=new byte[1024];  //每次做多读取1kb的数据
		int temp=0;
		while( (temp=fis.read(b))!=-1 ) {  //将数据读取到缓冲区,并返回读取的字节数(temp) ,-1表示读取完了
			System.out.println(new String(b,0,temp));  //String有将字节数组转换位String的构造方法
		}		
	}

二、序列化流:ObjectInputStream 和 ObjectOutputStream

  • 在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存,这就需要用到序列化流。比如最常见的是Web服务器中的Session对象,当有10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些seesion先序列化到硬盘中,等要用了,再把保存在硬盘中的对象还原到内存中,说白了,就是能将一个2进制文件变成内存中的对象。
  • JAVA的自定义实体类,是没有getByte()方法的,无法将对象直接转换成字节流,那么对象应该怎么进行传输?
    在JAVA中,要实现这种机制,只要实现Serializable接口就可以了,先看下面这个简单例子,serialVersionUID稍后引出。
  • 我们先定义一个简单的Person类,然后创建这个对象,最后序列化它到一个文件。
public class Person implements Serializable {   //注意:这里用来Serializable接口   
    private String name;     
    public String getName() { 
        return name; 
    } 
    public void setName(String name) { 
        this.name = name; 
    } 
} 

/将对象序列化到一个文件中**/

public class WhySerialversionUID {   
public static void main(String[] args) throws Exception {        
Person person= new Person(); 
person.setName("jack");   

File file = new File("E://jack.test");   //创建file
FileOutputStream fileoutStream =new FileOutputStream(file ); //为创建字节输出流对象
ObjectOutputStream oo = new ObjectOutputStream  (fileoutStream );  //创建对象输出流对象

oo.writeObject(person); 
oo.close();

/还原文件*/

 ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("E://jack.test")));
Person person = (Person)ois.readObject();     
String name= person.getName();
System.Out.Print("name is: "+name);

一切都那么顺利,但是如果在序列化之后,Person这个类发生了改变呢?比如,多了一个成员变量。之后,我们再去运行一下还原,就发现运行出错了。这是因为类只要一改边,那么类中的serialVersionUID就会改变,虽然类中我们没有指定serialVersionUID这个变量,但编译器会自动为我们添加一个。要杜绝这种错误,可以显示的添加一个serialVersionUID变量,这样当序列化存储之后,类即便改变了,serialVersionUID的值也不会变化,依然可以序列化还原。

/自己添加serialVersionUID变量**/

private static final long serialVersionUID = 1L;

class Person implements serialVersionUID{ } 后代码的左边会出现一个感叹号,点击一下系统即可自动生成唯一的serialVersionUID值。

三、字符输入流

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值