IO流,FileWriter,FileReader,BufferInputStream,BufferOutputStream等使用

IO流(eclipse)

IO流的概念

IO:input(输入)读取文件中的数据
output(输出)将程序中的数据写入到文件之中

IO的分类

文件流

  • FileReader 读文件(字符流)
  • FileWriter 写文件(字符流)
  • FileInputStram 读文件(字节流)
  • FileOutputStream 写文件(字节流)

字符流及对应缓冲区FileWriter,FileReader,Buffer···

public static void main(String[] args) {
		FileWriter fw = null;
		FileReader fr = null;
		try {
			fw = new FileWriter("一个文件");
			fw.write("插入字符abc");
			fw.flush(); // 把缓冲区的数据刷入硬盘
			fr = new FileReader("一个文件");
			char[] buf = new char[1];
			int realCount = fr.read(buf);
			while (realCount != -1) {
				// 处理数据
				System.out.print(buf);
				// .... 
				// 继续读				
				realCount = fr.read(buf);	
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

这个是比较普通的IO流写法,通常我们在传输文章数据时,会用这个方法,然而,当你想要传输音乐或者是视频文件的时候,则会出现错误,这个错误既不是编译错误也不是运行错误
因为我们的这个方法是字符流传输,是两个字节,而音乐和视频是一个字节,是使用字节流传输的
而且我们想要读取这个文件中的信息,我们还要用字符将文件中的字符提取出来,然后再通过判断是否读到最后,输出得到的字符,这样太麻烦了,一个字符一个字符读对于硬盘的利用率来说就是灾难
那么该怎么办呢,我们可以设置一个缓冲区,一次性的读取硬盘一个扇面的一大堆数据,然后再去处理

public static void main(String[] args) {
		FileWriter fileWriter = null;
		BufferedWriter bufferedWriter = null;
		try {
			fileWriter = new FileWriter("一个文件");
			bufferedWriter = new BufferedWriter(fileWriter);
			String[] content = {"asldfkjalskjdflkasjfd",
								"我要写一些数据到文本文件",
								"再来一行",
								"再来一行吧...."};
			for (String string : content) {
				bufferedWriter.write(string);
				bufferedWriter.newLine();// 最有价值方法, 写入跨平台的换行
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (bufferedWriter != null) {
				try {
					bufferedWriter.close();
				} catch (Exception e2) {
				}
			}
		}
	}

源节点(文件)>>>filereader(读文件)>>>bufferedreader(缓冲区)>>>程序
程序>>>bufferedwriter(缓冲区)>>>filewriter(写文件)>>>目标节点(文件)
缓冲区是为了更高效的利用硬盘,不同的缓冲区对应不同的读写方法

字节流及对应的缓冲区FileOutputStream

缓冲流:(输入流):BufferedInputStream、BufferedReader
(输出流):BufferedOutputStream、BufferedWriter

FileOutputStream fos = null;
		BufferedOutputStream bos = null;
		try {
			fos = new FileOutputStream("一个文件");
			bos = new BufferedOutputStream(fos);
			String[] content = {"asldfkjalskjdflkasjfd",
								"我要写一些数据到文本文件",
								"再来一行",
								"再来一行吧...."};
			bos.write(1);
			//bos.write("w");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (bos != null) {
				try {
					bos.close();
				} catch (Exception e2) {
				}
			}
		}

这个时候我们用字节流输入,结果发现这个方法太可怜了,只能输入int,byte,输入一个String类型的数据都显示编译报错,那么我们来试着改善

可序列化对象

我们可以使用Serializable接口,直接添加对象,也可以使用ObjectOutputStream类,将缓冲区放入这个可序列化对象里,这用我们就可以通过调用这个对象的方法来实现写入操作

class Student implements Serializable{
	private String name;
	private int age;
	private String gender;
	private int score;
	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 int getScore() {
		return score;
	}
	public void setScore(int score) {
		this.score = score;
	}
	public Student(String name, int age, String gender, int score) {
		super();
		this.name = name;
		this.age = age;
		this.gender = gender;
		this.score = score;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + ", gender=" + gender + ", score=" + score + "]";
	}
	
}
public class Test {
	public static void main(String[] args) {
		FileOutputStream fos = null;
		BufferedOutputStream bos = null;
		ObjectOutputStream oos = null;
		
		FileInputStream fis = null;
		BufferedInputStream bis = null;
		ObjectInputStream ois = null;
		try {
			fos = new FileOutputStream("序列化");
			bos = new BufferedOutputStream(fos);
			oos = new ObjectOutputStream(bos);
			
			Student s1 = new Student("夏新", 21, "男", 100);
			Student s2 = new Student("冷雪瞳", 21, "女", 90);
			Student s3 = new Student("舒月舞", 20, "女", 80);
			Student s4 = new Student("张妍", 19, "女", 70);
			List<Student> list = new ArrayList<Student>();
			list.add(s1);
			list.add(s2);
			list.add(s3);
			list.add(s4);
			/*oos.writeObject(new Student("夏新", 21, "男", 100));
			oos.writeObject(new Student("冷雪瞳", 21, "女", 90));
			oos.writeObject(new Student("舒月舞", 20, "女", 80));  		这个写法也是可以的
			oos.writeObject(new Student("张妍", 19, "女", 70));*/
			oos.writeObject(list);
			oos.flush();//刷新,我们不关闭这个执行写的对象也可以得到数据		
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			if(oos!=null) {
				try {
					oos.close();
				} catch (Exception e2) {
					// TODO: handle exception
				}
			}
		}
		try {
			fis = new FileInputStream("序列化");//选择我们要打开的文件
			bis = new BufferedInputStream(fis);
			ois = new ObjectInputStream(bis);
			//System.out.println(ois.readObject());
			List<Student> list = (List<Student>) ois.readObject();
			Iterator<Student> iterator = list.iterator();
			while(iterator.hasNext()) {
				System.out.println(iterator.next());
			}
			
		} catch (Exception e) {
			// TODO: handle exception
		}finally {
			if(ois!=null) {
				try {
					ois.close();
				} catch (Exception e2) {
					// TODO: handle exception
				}
			}
		}
	}
}

ObjectOutputStream这个类真是太贴近人的心意了,我们甚至可以通过这个类的对象调用writeobject方法来添加对象,这样子我们可以同过list数组来选择排序或者添加操作,所以ObjectOutputStream这个类的IO流中是必不可少的
在我们的Student类中,实现了Serializable{接口,事实上这个接口一个方法也没有,但是我们还是要执行实现接口这个操作,不然会出现错误显示未序列化
序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。
可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络(文件)之间。
序列化是为了解决在对对象流进行读写操作时所引发的问题。
序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,
implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造
一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以
将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。

转换流

OutputStreamWriter就是一个例子,我们可以通过在创建是传入参数
new OutputStreamWriter(fos, “gbk”);
第一个参数是确认是写入流的对象
第二个参数是确实控制数据的格式
通常情况下eclipse能看到的格式是gbk,用utf8格式在eclipse下则会出现乱码,写文本文件时编码方式就是utf8。
其实这个转换流用的很少,转来转去很麻烦,只要文件打开可视,谁在乎一个文字到底是由两个字节组成还是三个字节组成的呢?

个人总结

按流向来说可以分为输入流和输出流
按类型来说可以分为节点流,处理流,缓冲流,转换流,打印流和对象流

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值