36Java I/O流-----文件流、缓冲流、对象流

I/O流概述

I/O(Input/Output)流,即输人输出流,是Java中实现输人输出的基础,它可以方便地实现数据的输人输出操作。
I/O流有很多种,按照不同的分类方式,可以分为以下3类:

1.字节流和字符流

根据流操作的数据单位的不同,可以分为字节流和字符流。字节流以字节为单位进行数据的读写,每次读写一一个或多个字节数据;字符流以字符为单位进行数据的读写,每次读写一个或者多个字符数据。

2.输入流和输出流

根据流传输方向的不同,又可分为输人流和输出流。其中输人流只能从流中读取数据,而不能向其写人数据;输出流只能向流中写人数据,而不能从中读取数据。

3.节点流和处理流

根据流的功能不同,可以分为节点流和处理流。其中节点流也被称为低级资,是指可以从一个特定的I/0设备(如磁盘)读写数据的流,它只能直接连接数据源,进行数据的读写操作;处理流也被称为高级流,它用于对于一个已存在的节点流进行连接和封装,通过封装后的流来实现流的读写能力。当使用处理流时,程序不会直接连接到实际的数据源,而是连接在已存在的流之上

文件流

package day07;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

/**
 * 流
 * 流根据方向不同分为输入流与输出流,参照点为
 * 当前程序
 * 输入流用来读取数据,输出流用来写出数据
 * java.io.InputStream
 * 抽象类,定义了输入流的读取字节方法,所有的字节
 * 输入流都继承自它
 * 
 * java.io.OutputStream 则是所有字节输出流的父类
 * @author 
 *
 *
 *流分类节点流与处理流
 *节点流,也叫低级流,是负责读写数据的流
 *读写操作中必须要有低级流。数据源明确
 *
 *处理流,也叫高级流,读写可以没有高级流,
 *高级流也不能独立存在,必须用于处理其他流,
 *处理其他流的目的是简化读写数据中的操作
 *
 * java.io.FileOutputStream
 * 文件输出流,是一个低级流,作用是向文件中
 * 写出字节
 */
public class FOSDemo {

	public static void main(String[] args) throws IOException {
		/**
		 * 默认创建的FOS是覆盖写操作
		 * FOS会将文件数据(所有数据)全部
		 * 删除,然后在开始写
		 */
		FileOutputStream fos = new FileOutputStream("fos.txt");
		
		String str = "我爱北京天安门";
		/**
		 * String->byte[]
		 * 
		 * byte  getBytes()
		 * 将当前字符串按照系统默认字符集转换为一组字节
		 * 
		 * byte getBytes(String csn)
		 * 按照给定的字符集将当前字符串转换为一组字节
		 */
		byte[] data = str.getBytes("UTF-8");
		fos.write(data);
		System.out.println("写出完毕");
		fos.close();
	}

}

package day07;
/**
 * 文件输出流
 * 追加写操作
 */
import java.io.FileOutputStream;
import java.io.IOException;
public class FosDemo2 {
	public static void main(String[] args) throws IOException{
		/**
		 * 在创建FOS时,若指定第二个参数,
		 * 并且该值为true时,则是追加
		 * 写操作,那么本次通过FOS写出
		 * 的内容会被追加到该文件末尾
		 */
		FileOutputStream fos= new FileOutputStream("fos.txt",true);
		fos.write("哦".getBytes("UTF-8"));
		System.out.println("写出完毕");
		fos.close();
	}
}
package day07;

import java.io.FileInputStream;
import java.io.IOException;

/**
 * Java.io.FileInputStream
 * 文件输入流,是一个低级流,用于
 * 从文件中读取字节
 * @author 
 *
 */
public class FosDemo3 {

	public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("fos.txt");
		byte[] data = new byte[100];
		int len = fis.read(data);
		String str = new String(data,0,len,"UTF-8");
		System.out.println(str);
		fis.close();
	}

}
package day07;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 使用文件流复制文件
 * @author 
 *
 */
public class CopyDemo {

	public static void main(String[] args) throws IOException {
		/**
		 * 使用文件输入流读取文件,再使用
		 * 文件输出流向目标文件中写
		 * 顺序从原文件中读取每个字节并写入到
		 * 目标文件即可完成复制
		 */
		FileInputStream src = new FileInputStream("课后答案.txt");
		FileOutputStream desc = new FileOutputStream("课后答案44.txt");
		byte[] buf = new byte[1024*10];
		int len = 10;
		while ((len = src.read(buf))!=-1) {
			desc.write(buf,0,len);
		}
		System.out.println("复制完毕");
		src.close();
		desc.close();

	}

}

缓冲流

package day07;
/**
 * 缓冲流
 * java.io.BufferedInputStream
 * java.io.BufferedOutputStream
 * 缓冲字节输入输出流是一对高级流,使用他们
 * 可以加快读写效率
 * 
 * 高级流可以处理其他流,但是无论添加了多少高级流
 * 最底下都要有低级流,因为低级流是真实
 * 读写数据的流,高级流都是处理数据的
 * 高级流处理其他流形成了流的链接,并且有效的
 * 组合不同的高级流可以得到叠加的效果 
 */
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 使用缓冲流加快读写效率
 * 
 * @author Administrator
 */
public class CopyDemo2 {
	public static void main(String[] args)throws IOException {
		FileInputStream fis = new FileInputStream("课后答案.txt");
		BufferedInputStream bis = new BufferedInputStream(fis);
		
		
		FileOutputStream fos = new FileOutputStream("7777.txt");
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		
		
		int d = -1;
		/**
		 * 缓冲流内部有一个缓冲区
		 * 当bis.read方法读取第一个字节时
		 * 实际上BIS会一次性读取一组字节并存入内部
		 * 的字节数组中,然后将第一个字节返回,
		 * 当再次调用read方法时,BIS直接从字节数组中
		 * 将第二个字节返回,直到字节数组中所有字节全部返回后
		 * 才会再次读取一组字节
		 * 所以缓冲流也是依靠提高一次读写的数据量减少读写
		 * 次数来达到提高读写的效率的
		 */
		while ((d = bis.read()) != -1) {
			bos.write(d);
		}
		
		System.out.println("复制完毕");
		/*
		 * 关闭流时,只关闭最外层的高级流即可
		 */
		bis.close();
		bos.close();

	}
}

package day07;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 缓冲输出流写出数据的注意事项
 * @author Administrator
 *
 */
public class BosDemo {
	public static void main(String[] args) throws IOException{
		FileOutputStream fos
			= new FileOutputStream("bos.txt");
		BufferedOutputStream bos
			= new BufferedOutputStream(fos);				
		String str = "就是因为这句话审核不通过";
		byte[] buf = str.getBytes("UTF-8");
		bos.write(buf);
		/*
		 * 强制将当前缓冲流中的缓冲区中的数据
		 * 全部写出,无论缓冲区是否被装满
		 */
		bos.flush();
		System.out.println("写出完毕");
		//close时,也会自动调用一次flush
		bos.close();
	}
}

对象流

package day07;
/**
 * 该类用于测试作为对象流读写对象使用
 */
import java.io.Serializable;
import java.util.List;
/**
 * 一个对象若想通过ObjectOutputStream
 * 进行序列化(被对象流读写),那么该对象所属的类必须实现
 * Serializable接口
 * 该接口没有定义任何抽象方法,实现该接口
 * 仅仅用于标识当前类的实例可以被序列化
 * @author Administrator
 *
 */
public class Person implements Serializable{
	/**
	 * 当一个类实现了Serializable接口后
	 * 应当添加一个常量:serialVersionUID 
	 * 该常量为当前类的序列化版本号,若不定义
	 * 系统会根据当前类的结构生成,但是只要类的
	 * 结构发生改变,版本号也会发生改变
	 * 
	 * 版本号影响着反序列化的结果。即:
	 * 当OIS对一个对象进行反序列化时,会检查
	 * 该对象与类的版本是否一致:
	 * 若一致:反序列化成功,但是若该对象与类
	 * 的结构不一致时 ,则采用兼容模式,能还原的属性
	 * 都还原
	 * 若不一致:反序列化直接抛出版本不一致异常
	 */
	private static final long serialVersionUID = 1L;
	/*
	 * 当类的属性增加或修改了,若版本号不变
	 * 那么反序列化时会尽可能兼容现有版本
	 * 若版本号发生了改变,那么反序列化时会
	 * 抛出异常。
	 */
	private String name;
	private int age;
	private String gender;
	/**
	 * transient关键字用来修饰属性
	 * 当被修饰后,该类实例在使用OOS进行对象
	 * 序列化时,该属性值被忽略,从而达到对象“瘦身”
	 * 的目的
	 */
	private transient List<String> otherInfo;
	
	public Person() {
		
	}

	public Person(String name, int age, String gender, List<String> otherInfo) {
		super();
		this.name = name;
		this.age = age;
		this.gender = gender;
		this.otherInfo = otherInfo;
	}

	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 String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public List<String> getOtherInfo() {
		return otherInfo;
	}

	public void setOtherInfo(List<String> otherInfo) {
		this.otherInfo = otherInfo;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", gender=" + gender + ", otherInfo=" + otherInfo + "]";
	}
	
	
	
}

package day07;
/**
 * 对象流
 * 对象流是一对高级流,作用是方便读写Java中的对象
 * java.io.ObjectOutputStream
 * 对象输出流,可以将给定的对象转换为一组字节
 * 后写出
 */
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;

public class OOSDemo {
	public static void main(String[] args) throws IOException{
		Person p = new Person();
		p.setName("张三");
		p.setAge(15);
		p.setGender("男");
		List<String> otherInfo = new ArrayList<String>();
		otherInfo.add("是一个学生");
		otherInfo.add("喜欢打游戏");
		p.setOtherInfo(otherInfo);
		FileOutputStream fos = new FileOutputStream("person.obj");
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		/**
		 * ObjectOutputStream的writeObject
		 * 方法可以将给定对象转换为一组字节后写出。这些
		 * 字节比该对象实际内容要大,因为除了数据外还有结构等描述信息
		 * 
		 * 下面的代码实际上经历了两个操作:
		 * 1:oos将Person对象转换为一组字节
		 * 将一个对象转换为一组字节的过程
		 * 称为:对象序列化
		 * 
		 * 2:再通过fos将这组字节写入到硬盘
		 * 将该对象转换的字节写入到硬盘
		 * 做长久保存的过程称为:对象持久化
		 */
		oos.writeObject(p);
		System.out.println("写出对象完毕");
		oos.close();
		
	}
}

package day07;
/**
 * java.io.ObjectInputStream
 * 对象输入流,作用是
 * 读取一组字节并还原为对象
 * OIS读取的字节必须是有OOS将对象序列化
 * 得到的字节,否则会抛出异常 
 */
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class OISDemo {
	public static void main(String[] args) throws IOException, ClassNotFoundException{
		FileInputStream fis = new FileInputStream("person.obj");
		
		ObjectInputStream ois = new ObjectInputStream(fis);
		//对象反序列化
		Person p = (Person)ois.readObject();
		
		System.out.println(p);
		
		ois.close();
	}
}

猜你喜欢

转载自blog.csdn.net/qq_44787898/article/details/103300844
今日推荐