java io包字节流类图详解

在学长的要求下,我作为刚进入IT界不到两个月的小白鼠,利用了两天时间制作了一份关于java io包的字节流的ppt,并决定将其写成自己的第一篇博客。大牛看到本文槽点望请及时与作者联系,新人入门不喜勿喷,谢谢。

首先我们来看一看io包中的字节流类库图。

本文将按着接口,InputStream类,OutputStream类,子类实例的顺序进行讲解。

##一 、包中接口 ##
ObjectInput接口:ObjectInput 扩展 DataInput 接口以包含对象的读操作。DataInput 包括基本类型的输入方法;ObjectInput 扩展了该接口,以包含对象、数组和 String 的输出方法。其子接口有:
InputStream
ObjectOutputStream
ObjectInputStream

DataInput接口:用于从二进制流中读取字节,并根据所有 Java 基本类型数据进行重构。同时还提供根据 UTF-8 修改版格式的数据重构 String 的工具。后文出现的实现类有:
DataInputStream
ObjectInputStream

DataOutput 接口:用于将数据从任意 Java 基本类型转换为一系列字节,并将这些字节写入二进制流。同时还提供了一个将 String 转换成 UTF-8 修改版格式并写入所得到的系列字节的工具。后文出现的DataOutput 接口的实现类有:
ObjectOutputStream
DataOutputStream
RandomAccessFile

ObjectOutput 接口:扩展 DataOutput 接口以包含对象的写入操作。DataOutput 包括基本类型的输出方法;ObjectOutput 扩展了该接口,以包含对象、数组和 String 的输出方法。后文出现的ObjectOutput接口实现类有:
ObjectOutputStream
##二、InputStream及其子类##

此抽象类是表示字节输入流的所有类的超类,继承该类的子类能够实现对数据的读取 。InputStream的作用是用来表示那些从不同数据源产生输入的类。
InputStream读取数据源及其对应子类:

1)字节数组 – ByteArrayInputStream

2)String对象 – StringBufferInputStream

3)文件 – FileInputStream

4)“管道”:从一端输入,从另一端输出 – PipedInputStream

5)一个由其他种类的流组成的序列 – ObjectInputStream

6)其他数据源,如音频文件 – AudioInputStream

三、OutputStream及其子类##

OutputStream类别的类决定了输出所要去的目标,这些目标包括及其对应子类:

1)字节数组 – ByteArrayOutputStream

2)文件 – FileOutputStream

3)“管道” – PipedOutputStream

四、应用子类实例##

  1. 读取音频文件的AudioInputStream
    需求说明:现在我们要用AudioInputStream 读取C:\Users\lenovo\Music目录下的音频文件”逃跑计划 - 夜空中最亮的星.wav“。
File f = new File("C:\\Users\\lenovo\\Music\\逃跑计划 - 夜空中最亮的星.wav");
		byte[] b = new byte[1024];

		try(AudioInputStream as = AudioSystem.getAudioInputStream(f);){
			//将音频文件读取字节数组中
			as.read(b);

		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println(b[0]);

注意:AudioInputStream读取的音频文件必须是wav格式的。
备注:本文为了验证成功读取文件使用System.out.println(b[0])查看b中的数据。

2.读取字节数组的ByteArrayInputStream
需求说明:现在我们要用ByteArrayInputStream 读取”F:\1.txt文件”。

	byte buf[] = new byte[1024];
	byte b[] = new byte[1024];
	// 创建一个 ByteArrayInputStream,使用 b作为其缓冲区数组。
	try(InputStream is = new FileInputStream("C:/Users/lenovo/Music/Justin Bieber - Love Yourself.mp3");
	ByteArrayInputStream bais = new ByteArrayInputStream(b);)
	{
		is.read(b);
		//将数据此输入流读入 byte数组
		bais.read(buf);
	} catch (Exception e) {
		e.printStackTrace();
	}
	System.out.println(buf[0]);

3.写入字节的ByteArrayOutputStream
需求说明:现在我们要用ByteArrayOutputStream 接收输入流中的数据,然后将数据写入字节数组。

	int temp = 0;
	//创建输入输出流对象
	try(InputStream is = new FileInputStream("C:/Users/lenovo/Music/Justin Bieber - Love Yourself.mp3");
		ByteArrayOutputStream baos = new ByteArrayOutputStream())
	{
		//将输入流中的数据写入输出流
		while((temp=is.read())!=-1){
			baos.write(temp);
		}
		//将输出流中的数据导出到字节数组中
		byte[] b = baos.toByteArray();

		System.out.println(b[0]);
	} catch (Exception e) {
		e.printStackTrace();}

4.读取文件的FileInputStream
需求说明:现在我们要用FileInputStream 将文件中的数据读入字节数组。

byte[] b = new byte[1024];
try(InputStream is = new FileInputStream("F:/1.txt"))
{
	//将文件中的数据读入字节数组
	is.read(b);	
	} catch (Exception e) {
		e.printStackTrace();
	}
	System.out.println(b[0]);

5.将数据写入文件的FileOutputStream
需求说明:将”1.txt“文件复制到一个指定路径的新文件”2.txt“中。

	int temp = 0;
	//创建文件读取输出流
	try(InputStream is = new FileInputStream("F:/1.txt");
        FileOutputStream fos = new FileOutputStream("F:/3.txt"))
	{
		while((temp=is.read())!=-1){
			fos.write(temp);	
		}
	} catch (Exception e) {
		e.printStackTrace();
	}

6.接受写入管道输出流的所提供的数据字节的PipedInputStream
需求说明:利用PipedInputStream读取管道输出流中的数据。

	//创建一个管道输入流
	PipedInputStream pis = new PipedInputStream();
	byte a[] = new byte[]{1,2,3,4,5,6};
	byte b[] = new byte[1024];
	//创建一个管道输出流
	PipedOutputStream pos = new PipedOutputStream();
	//将字节数组写入管道输出流
	try{	//将输出流管道与输入流管道连接,不连接将抛出IO
		pos.connect(pis);
		pos.write(a,0,5);
		//刷新管道输入流
		pos.flush();
		//读取管道输出流中的数据
		pis.read(b);
		System.out.println(b[0]);
	} catch (IOException e) {
		e.printStackTrace();
	}finally{	//关闭管道输入流和管道输出流
		try {	pos.close();	
			pis.close();
		} catch (Exception e) {
			System.out.println("发生IO异常!");}}

7.将数据写入管道的PipedOutputStream
需求说明:将字节数组写入管道输出流PipedOutputStream中。代码展示如上例。

8.将其他输入流逻辑串联,依次读取的SequenceInputStream
需求说明:将两个输入流连接在一起,依次读取两个输入流的数据。

	byte[] b = new byte[1024];
	try(InputStream is1 = new FileInputStream("F:/1.txt");
	InputStream is2 = new FileInputStream("F:/2.txt");
	//创建SequenceInputStream对象,将两个输入连接
             SequenceInputStream sis = new SequenceInputStream(is1,is2);)
	{
		//依次读取两个输入流
		sis.read(b);
	} catch (IOException e) {
		e.printStackTrace();}
	System.out.println(b[0]);

9.从文件中读取类的ObjectInputStream
需求说明:将ObjectOutputStream向文件中写入的类利ObjectInputStream读取出来。

	FileInputStream fis = new FileInputStream("F:/1.tmp");
		//创建读取类的ObjectInputStream对象
		ObjectInputStream ois = new ObjectInputStream(fis);
		FileOutputStream fos = new FileOutputStream("F:/1.tmp");
		//创建写入类的ObjectOutputStream对象
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		//利用writeObject()方法向指定文件写入类
		oos.writeObject("Today");
		oos.close();
	//利用readObject()方法读取指定文件的类返回的是object类,所以要进行强转
		String time =(String)ois.readObject();
		ois.close();
		
		System.out.println(time);

10.向指定文件写入类的ObjectOutputStream
需求说明:利用ObjectOutputStream向文件中写入类。展示代码入上例。

11.StringBufferInputStream类现已过时在此不做使用说明。

12.FilterInputStream类展开,对其及其子类进行详细说明。

FilterInputStream包含其他一些输入流,它将这些流用作其基本数据源,它可以直接传输数据或提供一些额外的功能。FilterInputStream 的子类可进一步重写这些方法中的一些方法,并且还可以提供一些额外的方法和字段。FilterInputStream的子LineNumberInputStream已过时不做说明
对FilterInputStream 的子类进行说明。

(1)缓冲输入以及支持 mark 和 reset 方法的BufferedInputStream
需求说明:利用BufferedInputStream接受键盘输入的数据。

byte b[] = new byte[1024];
	try(	BufferedInputStream bis = new BufferedInputStream(System.in);
		DataInputStream  dis = new DataInputStream(bis);)
		{	//在输入流处做好标记,并保留1024位
			dis.mark(1024);
			//将键盘输入的数据读入字节数组b中
			dis.read(b);
			String a1 = new String(b,0,b.length);
			System.out.println(a1);
			//重新回到之前的标记处,再次读取数据
			dis.reset();
			dis.read(b);
			String a2 = new String(b,0,b.length);
			System.out.println(a2);
		} catch (IOException e) {
			e.printStackTrace();}

(2)校验和可用于验证输入数据的完整性的CheckedInputStream
需求说明:验证数据的完整性后,将数据读入数组。

byte b[] = new byte[1024];
		//指定的校验和 ,Adler32是可用于计算数据流的 Adler-32 校验和的类
		Checksum c = new Adler32();
		try(InputStream is = new FileInputStream("F:/1.txt");
			CheckedInputStream cis = new CheckedInputStream(is, c))
		{
			//返回当前的校验和值
			c.getValue();
			//将数据读入字节数组
			cis.read(b);
			cis.close();
			System.out.println(b[0]);
		} catch (Exception e) {
			e.printStackTrace();}	

(3)读取加密数据的CipherInputStream
需求说明:利用CipherInputStream将加密数据读入。

	InputStream is = null;
	//service为具体的值
	try {	is = new FileInputStream("service");
		//实例化KeyGenerator对象,指定一个算法 ,DES是一种转换名称,其他CBC、PKCS5Padding
		KeyGenerator kg = KeyGenerator.getInstance("DES");
		//生成SecretKey对象
		SecretKey secrekey = kg.generateKey();
		//实例化Cipher对象
		Cipher c = Cipher.getInstance("DES");
		//初始化Cipher对象,用于解密操作。
		c.init(Cipher.DECRYPT_MODE,secrekey);
		CipherInputStream cis = new CipherInputStream(is, c); 
		//使用DataInputStream对象包装CipherInputStream对象
		DataInputStream dis = new DataInputStream(cis);
		//将数据读入到字节数组
		String utf = dis.readUTF();	
			System.out.println(utf);
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			try {i	s.close();
			} catch (IOException e) {
				e.printStackTrace();}}

(4)使用通过流的位更新关联消息摘要的透明流DigestInputStream
需求说明:利用DigestInputStream将数据读入,并带有消息摘要。

//使用指定的输入流和消息摘要创建一个摘要输入流。
	InputStream is;
	MessageDigest md;
	DigestInputStream dis = null;
	byte b [] = new byte[1024];
	try {	is = new FileInputStream("F:/1.txt");
		//此 MessageDigest 类为应用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法
		md = MessageDigest.getInstance("MD5");
		dis = new DigestInputStream(is, md);
		//读取字节并更新消息摘要(如果开启了摘要功能)
		dis.read(b);
		System.out.println(b[0]);
	} catch (Exception e) {
		e.printStackTrace();
	}finally{	try {
			dis.close();
			} catch (IOException e) {
				e.printStackTrace();}}

(5)监视读取某些 InputStream 进度的ProgressMonitorInputStream
需求说明:利用DigestInputStream将数据读入,并进行监视。

InputStream is;
	ProgressMonitorInputStream pmis = null;
	byte b[] = new byte[1024];
	try{
		is = new FileInputStream("F:/1.txt");
		String a = "Reading"+"F:/1.txt"; 
		//构造一个对象,以监视输入流的进度。
	pmis = new ProgressMonitorInputStream(new Button(), a, is);
		//重写 FilterInputStream.read,以读取之后更新进度监视器。
		pmis.read();
		System.out.println(b[0]);
	} catch (Exception e) {
		e.printStackTrace();
	}finally{	try {
			pmis.close();
			} catch (IOException e) {
				e.printStackTrace();}}

(6)拥有推回和取消读取字节能力的PushbackInputStream
需求说明:利用PushbackInputStream将数据读入,并将数据推回,再次读取。

byte b[] = new byte[1024];
	int num = 1;
	try(InputStream is = new FileInputStream("F:/1.txt");
	PushbackInputStream pis = new PushbackInputStream(is);)
	{
		pis.read(b);
		System.out.println(b[0]);
		//推回一个 byte数组:将其复制到推回缓冲区之前
		pis.unread(num);
		pis.read(b);
			
		System.out.println(b[0]);
	} catch (Exception e) {
		e.printStackTrace();}

(7)允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型的DataInputStream
需求说明:利用DataInputStream将数据读入。

		byte[] b = new byte[1024];
		try(InputStream is = new FileInputStream("F:/2.txt");
		DataInputStream dis = new DataInputStream(is);)
		{
		//从输入流中读取字节,并将它们存储在缓冲区数组 b中
			dis.read(b);

			System.out.println(b[0]);
		} catch (Exception e) {
			e.printStackTrace();
		}

(8)FilterInputStream下的特殊子类InflaterInputStream

InflaterInputStream为解压缩 “deflate” 压缩格式的数据实现流过滤器,其两个子类分别为:读取 ZIP 文件格式的文件实现输入流过滤器ZipInputStream和
读取 GZIP 文件格式的压缩数据实现流过滤器GZIPInputStream。

a.为读取 ZIP 文件格式的文件实现输入流过滤器的ZipInputStream

ZipInputStream可以得到压缩实体,但得不到压缩实体的流,流存贮在ZipEntry对象中。所以要想获得文件相对应的数据必须,将对应文件的ZipEntry对象创建出来。
每个压缩文件中都会存在多个子文件,每个子文件在java中ZipEntry来表示。
ZipInputStream对应的输出流类ZipOutputStream。
GZIPInputStream用于对GZIP格式的文件进行操作,GZIP 格式的文件用于UNIX系统的文件压缩,本ppt就不做详解,其对应输入流为DZIPOutputStream。对于文件的处理机制类似于ZipInputStream。
现在我们来看看利用ZipInputStream如何处理文件。

try(InputStream is = new FileInputStream("F:/2.txt");
	ZipInputStream zis = new ZipInputStream(is);
	FileOutputStream fos = new FileOutputStream(new File("F:/2.zip"));
	ZipOutputStream zos = new ZipOutputStream(fos);	)
	{	//设置ZipEntry对象 
		ZipEntry ze = new ZipEntry("F:/2.txt");
		// 设置ZipEntry对象 
		zos.putNextEntry(ze);
		int temp = 0 ;  
		//将要压缩的文件利用ZipInputStream对象读入输出流中
		while((temp=zis.read())!=-1){ // 读取内容  
			zos.write(temp) ;    // 压缩输出  } 
				
			System.out.println(ze.getName());
		} catch (Exception e) {
			e.printStackTrace();
		}

b.对jar文件进行处理的特殊类:JarInputStream

jar压缩的支持类包括:
1)jar压缩输出流:JarOutputStream
2)jar压缩输入流:JarOutputStream
3)jar文件:JARFILE
4)jar实体:JAREntry
接下来对jar压缩进行举例说明。

		//创建输入输出流
try(	JarInputStream jis = new JarInputStream(new FileInputStream("F:/2.txt"));
	JarOutputStream jos = new JarOutputStream(new FileOutputStream("F:/2.jar")))
		{
			//创建对应的JarEntry对象
			JarEntry ze = new JarEntry("F:/2.txt");
			//向输出流中设置ZipEntry对象
			jos.putNextEntry(ze);
			//将文件压缩输出
			int temp = 0;
			while((temp=jis.read())!=-1){
				jos.write(temp);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

注:该实例直接使用FileInputStream类,未使用JarFile类

(9)对文件进行随机读取的RandomAccessFile

//public RandomAccessFile(File file, String mode)
//该构造方法创建从中读取和向其中写入(可选)的随机访问文件流,该文件由 File 参数指定。
//mode 参数指定用以打开文件的访问模式
	File f = new File("F:/1.txt");
	try(RandomAccessFile raf = new RandomAccessFile(f,"rw");)
	{
		//随机读取文件中的一个字节
		int num = raf.read();
		
		System.out.println(num);
	} catch (Exception e) {
		e.printStackTrace();
	}

##五.作者总结 ##
通过写作该本的制作收获以下心得体会:
1、在进行流操作时,最后一定要将流关闭。该ppt中的实例,作者根据不同的情况,采用了不同的关流方法,包括java7中的Try-With-ResourcesStatement格式。
2、每个特定流的类,可能都有它的特定格式,理解了这种格式,有利于对流的运用。
3、基本上每个特定的InputStream类都有对应的OutputStream类,其实不同类在文件的读取和写入上都存在共同点。

备注:
FilterOutputStream中的子类并未挨个展开,其原理和使用与其他的OutputStream一致。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值