IO流简介

我们为什么需要IO流?

  我大学主修的专业是电路硬件与通信,我觉得先从硬件上理解IO会更容易一些。

  IO就是取了Input和Output的首字母,就是输入和输出的意思。在硬件上的IO接口,是分别用来接输出设备与输出设备的。因为电路与人类,毕竟不是同一种类,无法直接交流。那么,我们人类如何与单片机、电脑等硬件交流呢?这时就有了输入(Input)设备:鼠标、键盘、麦克风;输出(Output)设备:屏幕、扬声器、打印机等。

  我们写的Java主程序,就相当于单片机、电脑,程序的运行需要数据,而数据的获取往往需要跟外部系统进行通信。Java 的 IO流,就是广泛应用于文件传输和网络编程中的数据通信处理技术。

IO流

  Java中,IO流主要可以分为五个部分:数据源、输入流、主程序、输出流、目的数据源。

  其中,数据源和目的数据源的表现形式有多种,可以为:文件、数据库、其他程序、内存、网络连接等。

  而其中的输入输出流是相对于主程序来说的,也是我们在IO流技术中需要掌握的。

  大致的传输过程,可以图形化表示如下:
在这里插入图片描述

IO流类体系

  在Java IO流技术中,常用的抽象类与实现类的关系图如下:
在这里插入图片描述

IO流的分类

输入流与输出流

  按流的方向分类,可以将流分为输入流与输出流:

  • 输入流:数据流向是数据源到程序(以InputStream、Reader结尾的流)。
  • 输出流:数据流向是程序到目的地(以OutPutStream、Writer结尾的流)。

字节流与字符流

  按流的数据单位分类,可以分为字节流与字符流:

  • 字节流:以字节为单位获取数据,InputStream/OutputStream抽象类的子类为字节流。
  • 字符流:以字符为单位获取数据,Reader/Writer抽象类的子类为字符流。

字节数组byte[]、字符数组char[]与字符串String

  要理清字节流与字符流,就先要清楚字节数组byte[]、字符数组char[]与字符串String之间的关系。

  byte与char都是基本数据类型。其中byte是数值型,占1字节空间,char字符型占2字节的空间。

  char是可以转换为byte的,但需要有规定的字符集,而且不同字符集的转换规则不一样,常见的字符集转换时字节个数:

  • UTF-8编码中,一个英文字符等于一个字节,一个中文(含繁体)等于三个字节。

  • Unicode编码中,一个英文等于两个字节,一个中文(含繁体)等于两个字节。符号:英文标点占一个字节,中文标点占两个字节。

  • GBK编码方式是中文占两个字节,英文占1个字节。

  关于字符集,就按字典、键值对的方式理解。如在UTF-8中:a对应97,‘我’对应{-2,-120,111},是固定且一一对应的。

  字符串String类型,就是字符数组char[]的一种实现类。类中提供了与字节数组、字符数组相互转换的方法。所以我们可以通过String,快捷方便地实现字节数组byte[]与字符数组char[]的相互转换。

编码

  我们把字符串转换为字节数组的过程,称为编码(由人可以读懂到不可读懂)。实现案例:

public class Test {
	public static void main(String args[]) throws UnsupportedEncodingException{

		String str = "你我他";
		
		byte[] bytes = str.getBytes("UTF-8"); // String类提供的转byte方法,若不传入字符集,则选择Eclipse默认字符集
										    //若传入字符集与String的字符集不一致,则会乱码
		for (byte b : bytes) {
			System.out.print(b+",");
		}
		
	}
}
-------------------------------------------------------
输出结果为:
-28,-67,-96,-26,-120,-111,-28,-69,-106,    // 一汉字 , 3字节  
解码

  我们把字节数组转换为字符串的过程,称为解码(由人不可读懂到可读懂)。实现案例:

public class Test {
	public static void main(String args[]) throws UnsupportedEncodingException{

		byte[] bytes = {-28,-67,-96,-26,-120,-111,-28,-69,-106};
		
		String str = new String(bytes,0,bytes.length,"UTF-8"); // 通过String构造器,实现字节数组转String
		
		System.out.println(str);
		
	}
}
------------------------------------------------------
输出结果为:
你我他
String与字符数组char[]的转换

  编码与解码就是String与字节数组byte[]的转换,String与字符数组char[]的转换与其类似,但不用涉及字符集:

public class Test {
	public static void main(String args[]) throws UnsupportedEncodingException{
		String str = "你我他";
		
		char[] charArray = str.toCharArray();//String类的toCharArray方法,转数组
		
		for (char c : charArray) {
			System.out.print(c+",");
		}
		System.out.println();
		
		String str2 = new String(charArray,0,charArray.length);//调用String构造器,不涉及字节,所以不涉及字符集
		System.out.println(str2);
	}
}
------------------------------------------------------
输出结果为:
你,,,
你我他

节点流与处理流

  按处理的对象分类,可以将流分为节点流与处理流:

  • 节点流:可以直接从数据源或目的地读写数据,如FileInputStream、FileReader、DataInputStream等。
  • 处理流:不直接连接到数据源或目的地,是”处理流的流”。通过对其他流的处理提高程序的性能,如BufferedInputStream、BufferedReader等。处理流也叫包装流。

  处理流不可以单独直接使用,因为它需要有一个有数据的流,才能对流进行处理。

四大IO抽象类

  InputStream/OutputStream和Reader/Writer类是所有IO流类的抽象父类,我们有必要简单了解一下这个四个抽象类的作用:

InputStream

  此抽象类是表示字节输入流的所有类的父类。InputSteam是一个抽象类,它不可以实例化。 数据的读取需要由它的子类来实现。根据节点的不同,它派生了不同的节点流子类 。

  继承自InputSteam的流都是用于向程序中输入数据,且数据的单位为字节(8 bit)。

  常用方法:

  • int read():读取一个字节的数据,并将字节的值作为int类型返回(0-255之间的一个值)。如果未读出字节则返回-1(返回值为-1表示读取结束)。

  • void close():关闭输入流对象,释放相关系统资源。

OutputStream

  此抽象类是表示字节输出流的所有类的父类。输出流接收输出字节并将这些字节发送到某个目的地。

  常用方法:

  • void write(int n):向目的地中写入一个字节。

  • void close():关闭输出流对象,释放相关系统资源。

Reader

  Reader用于读取的字符流抽象类,数据单位为字符。

  • int read(): 读取一个字符的数据,并将字符的值作为int类型返回(0-65535之间的一个值,即Unicode值)。如果未读出字符则返回-1(返回值为-1表示读取结束)。

  • void close() : 关闭流对象,释放相关系统资源。

Writer

  Writer用于写入的字符流抽象类,数据单位为字符。

  • void write(int n): 向输出流中写入一个字符。

  • void close() : 关闭输出流对象,释放相关系统资源。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值