IO流

IO流

java IO 标准的输入和输出

  • 什么是输入:输入是一个从外界进入到程序的过程,是用来读取数据的
  • 什么是输出:输出是一个从程序发送到外界的过程,是用来写出数据的
  • 什么是流:java以统一的标准的读写形式定义了一套API,成为“流”。
    使用流可以读取任意设备(网络,文件,键盘,控制台等等)
  • java将流按照功能以方向的形式分为两类:
    • 输入流:input,是外界到我们写的程序的方向,使用输入流用于从外界获取数据,是读操作
    • 输出流:output,用于从将数据发送至外界,是写操作

java将流划分为节点流与处理流

  • 节点流:可以从一个特定的地方(节点)读写数据。又称为“低级流”,是真实连接程序与数据源的“管道”,负责实际搬运数据的流。
    读写一定是建立在低级流基础上进行的

  • 处理流:是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。又称“高级流或过滤流”,高级流不能独立存在,必须连接在其他流上,目的是当数据流经当前高级流时,对数据作某些加工处理,简化我们对数据的该操作.

  • 流的连接:串连一组高级流并最终连接在低级流上,在读写操作的过程中对数据进行一系列流水线式的加工处理,这种读写操作称为:流的连接

  • 流连接也是IO的精髓所在

举个例子:

水管就是现实版的低级流(节点流),真实连接用户和自来水厂。是输入流
热水器/净水器就是高级流(处理流/过滤流),不能单独存在,必须连接在其他流上,并且是对流过的数据进行加工处理
下水道是低级流。是输出流

文件流

  • 文件流:文件流是一对低级流,作用是读写文件数据。
  • 在功能上它们与RandomAccessFile一致。但RAF是基于指针的读写,特点是可以对任意文件读或写,并且能做到对文件数据编辑操作,读写灵活。
  • 文件流是基于java IO的流式读写,而流式读写是一种顺序读写形式,只能顺序向后读写,不能回退,但是基于流连接,串连高级流可以将复杂数据读写操作简单化。

FileOutputStream

  • 文件的字节输出流,使用该流可以以字节为单位将数据写入文件
  • 构造方法:第二个参数表示追加模式
    FileOutputStream(String path):文件路径("./file.txt")
    FileOutputStream(File file):File类型(new File("./file.txt"))
    FileOutputStream(String path ,boolean append)
    FileOutputStream(File file ,boolean append)
  • 可以读写数字(同样只写后8位),可以读写byte[]数组

注意:以上前两种创建方式创建的文件数处流是覆盖写操作,即:若指定的文件已存在,会先将该文件数据删除,然后通过当前流写出的内容作为该文件数据保存。比如:

	public static void main(String[] args) throws UnsupportedEncodingException, IOException {
		FileOutputStream fos = new FileOutputStream("fos.txt");
		String str = "来啦~老弟~";
		fos.write(str.getBytes("UTF-8"));
		System.out.println("写出完毕");
		fos.close();//注意要关闭
		
	}

//来啦~老弟~

	public static void main(String[] args) throws UnsupportedEncodingException, IOException {
		FileOutputStream fos = new FileOutputStream("fos.txt");在创建的同时,若文件已存在,会把原文件的内容清空
		String str = "在";//
		fos.write(str.getBytes("UTF-8"));
		str = "呢";
		fos.write(str.getBytes("UTF-8"));
		System.out.println("写出完毕");
		fos.close();
		
	}

//第二段代码执行完成后:在呢
//原文件内容被清除。

如果在构造方法中再传入第二个参数,是一个boolean值,该值位true时,文件写入方式是追加模式,即:若文件已存在,源文件内容不变,在文件末尾追加内容。

比如上例第二段如果改成FileOutputStream fos = new FileOutputStream(“fos.txt”,true);
输出结果变成:来啦~老弟~在呢

文件输出流不支持修改文件部分数据的操作,比如之前用RAF做的修改用户昵称操作,文件流做不到。因为RAF是基于指针的操作,很灵活。

FileInputStream

  • 文件的字节输入流,使用该流可以以字节为单位从文件中读取数据
  • FileInputStream(String name)
  • FileInputStream(File file)

缓冲流

  • java.io.BufferedOutputStream
  • java.io.BufferedInputStream
  • 缓冲流是一对高级流,在流连接中起到加速读写效率的作用
  • 缓冲流读写效率之所以高是因为数据在经过它时,一定会被转化位块读写。
  • 工作原理:缓冲输出流内部维护着一个缓冲区,每当我们向该流写数据时,会先将数据存入缓冲区,当缓冲区已满时,缓冲流会将数据一次性全部写出。

在这里插入图片描述

public static void main(String[] args) throws IOException{
		FileInputStream fis = new FileInputStream("a.tar.gz");
		BufferedInputStream bis = new BufferedInputStream(fis);//分开写
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("a2.tar.gz"));//也可以写在一句中
		long start = System.currentTimeMillis();
		int d = -1;
		while((d = bis.read())!=-1) {
			bos.write(d);
		}
		
		bis.close();
		bos.close();
		long end = System.currentTimeMillis();
		System.out.println("复制完毕,耗时:"+(end-start));
	}

注意:缓冲输出流写出数据是当缓冲区已满时才会写出。所以有时候文件极小,或是最后一点内容无法充满缓冲区时,会没有写出内容,这时需要flush方法

  • void flush()
    • 强制将缓冲流中缓冲区里的已缓存的数据一次性写出。
    • 频繁的调用flush会提高实际写出数据的次数,从而降低写出效率。但是可以保证数据写出的即时性(比如qq聊天就需要即时性)
    • close方法会自动调用flush方法
		public static void main(String[] args) throws IOException {
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("./bos.txt"));
		byte[] d = "莫回首".getBytes("UTF-8");
		bos.write(d);
		bos.flush();//flush可以立即执行一次写操作,提高即时性。但是频繁调用会降低效率
		bos.close();//close前会自动调用一次flush
		System.out.println("写出完毕");
	}

对象流

  • 对象流是一对高级流,在流连接中负责对任何对象进行读写(可以将对象与一组字节进行转换)
  • 一个类若希望被对象流读写,那么这个类必须要实现接口:Serializable
  • 对象输出流写对象的方法:void writeObject(Object obj)
    将给定对象按照其结构转换位一组字节后写出
  • 涉及到的术语:
    • 当对象经过OOS写出是,其将该对象按照结构转换为了一组字节,这个过程称为“对象序列化”,其逆向过程叫做“对象反序列化
    • 当序列化的这组字节再经过FOS写入到文件中(写入到磁盘作长久保存)这个过程成为“数据持久化
  • 对象序列化时用作存储或传输数据的,对象中有些数据不是必要的,就可以选择不保存,这时可以再相应的属性加上transient修饰符。

当一个属性使用transient修饰后,进行序列化时,这个值会被忽略。忽略不必要的属性可以达到对象序列化瘦身效果,减少不必要的资源开销

  • void writeObject(Object o) ,将给定的对象转化为一个字节序列后输出

  • Object readObject() ,从流中读取字节并转换为对象,注意是Object类型的对象

  • 对象输出流
    在这里插入图片描述

  • 对象输入流
    在这里插入图片描述

public static void main(String[] args) throws IOException {
		/*
		 * 将一个Person实例写入文件person.obj中
		 */
		String name = "苍老师";
		String gender = "女";
		int age = 18;
		String[] otherInfo = {
				"是一名演员","已婚","日本"
		};
		Person p = new Person(name,age,gender,otherInfo);
		System.out.println(p.toString());
		//对象输出流
		FileOutputStream fos = new FileOutputStream("person.obj");
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		/*
		 * 对象输出流写对象的方法:
		 * void writeObject(Object obj)
		 * 将给定对象按照其结构转换位一组字节后写出
		 */
		oos.writeObject(p);
		oos.close();
		System.out.println("写出完毕");
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值