Java

您所在的位置:网站首页 流Java Java

Java

#Java| 来源: 网络整理| 查看: 265

Java-输入输出流的简单看法与总结

 为什么Java中关于输入输出流(IO流)的对象为什么这么多,实在难以记忆,这可能是绝大多数人在学习关于Java此内容的问题,下面就来总结一下这个知识点,让这个困难得到解决。

一、理解Java的IO模型和框架

实际上对于Java输入输出流的所有概念在下图中就已经完整地体现了:

还有不得不提一下Java的IO框架:

弄明白上面两张图,你就可以说已经理解了Java的IO模型。

 首先,需要理解IO流的各个类是用来做什么的。比方说:InputStreamReader 类可以用来做什么,有什么用途?可能这个问题难道你了,因为这个类既包括字节流,也囊括了字符流,到底是哪一个流?

有一个规律:

末尾的单词决定其是哪一类IO流,所以在此例中,这为字符流;开始的单词决定的输入的流类型,或者目的地流类型;Reader是基于字符的输入操作流,InputStream是基于字节的输入操作流Writer是基于字符的输出操作流,OutputStream是基于字节的输出操作流输出/输出流的分类意味着这个类具有输出/读取的功能方法,而不以为这流本身会主动执行这些方法

 有些既可以是源,也可以是目的地,比如说File,因为我们既可以从文件中读取内容,也可以向文件中写入内容,所以File既可以与InputStream组合,也可以和OutputStream组合; 有些则只能是目的地,或源,比如说InputStream只能和Reader组合,而没有OutputStreamReader的组合。

 综上所述,InputStreamReader类使用来读取字节流数据,得到字符数据来供我对字符流数据进行操作的类,所以这也要求了InputStreamReader类中的大多数方法是基于字符的操作。

注意事项:不要错认为IO流操作过程中只有输出流会对数据进行转换,比如说字节流转为硬盘文件存储起来,输入流同样有转换数据的功能。

除了用于缓冲作用的流,输入流可以一下方式理解:

输出流可以这么理解:

 对于缓冲IO流的理解:其也是个流对象,不过被称为装饰类流,这主要是通过其对输入/出流对象装饰后,我们不再直接调用输入/出流的读写方法,而是调用它缓冲IO流的读写方法。但是这个理解还是不够到位。所有流对象也是位于内存中的,但是缓冲IO流对象还是一个实管理内存的工具,所以可以凭借此类来和内存直接打交道,优化内存管理,而直接使用输入输出流则没有此功能。

二、活学活用

注意事项:下面的例子没有进行异常处理以及流的关闭操作,实际上不够科学,但是这里不是重点,省略了。

将一个字符串转为文档储存起来:

面对这样一个例子,我们应当怎么做呢?

我们是否需要一个输出流对象以及一个输出流对象呢?

 其实是不需要的,因为输入流的作用是读取数据至内存(或者特殊的内存块:缓冲IO流),既然String对象以及位于内存中了,不需要输入流对象,只需要输出流对象即可。输出流的前缀很容易判断:因为我们生成一个文件,所以此前缀为File,输出流的后缀不妨先设置为OutputStream,我们打算对其进行字节流的操作,所以调用了一下的方法:

byte[] bytes = str.getBytes();,因为要求输出流的构造参数需要为为字节类型的数据。

注意事项:根据需要确定是否需要输入流以及输出流。

/** * @author Fisherman */ public class MyTry { public static void main(String[] args) throws IOException { FileWriter fileWriter = new FileWriter("Mystr.txt"); byte[] bytes = str.getBytes(); FileOutputStream fileOutputStream = new FileOutputStream("Mystr.txt"); fileOutputStream.write(bytes); fileOutputStream.close(); } }

 问题实际上就是确定2个前缀以及两个后缀,输出流的前缀很容易判断:因为我们生成一个文件,所以此前缀为File。输入流的后缀和输出流的前缀恰好是流的两端,一定要一致,这里先选择OutputStream,

当然我们也可以采用字符流的操作来进行,如下代码块:

/** * @author Fisherman */ public class MyTry { public static void main(String[] args) throws IOException { String str="hello world i am fisherman!!!!!1233"; char[] chars =str.toCharArray(); FileWriter fileWriter = new FileWriter("Mystr.txt"); fileWriter.write(chars); fileWriter.close(); } }

注意事项:这里不要遗漏掉fileWriter的close方法,否则会造成文件写出失败。

将一个文件复制到另一个文件

对于文件的相关操作,推荐使用字节流,并且可以采用缓冲IO流进行包装:

无缓冲IO流的文件复制代码块:

 这里是两个文件的输入和输出,以及都是使用字节流,所以显然IO流对象采用的是:FileInputStream以及FileOutputStream。

/** * @author Fisherman */ public class CopyFIle { public static void main(String[] args) throws IOException { File inFile = new File("1.txt"); File outFile = new File("2.txt"); FileInputStream fins = new FileInputStream(inFile); FileOutputStream fouts = new FileOutputStream(outFile); int c ; while (((c = fins.read()) != -1)) { fouts.write(c); } fins.close(); fouts.close(); } }

 由上面的代码我们可见其效率是比较低的,因为我们每次调用方法:fins.read()只能读取一个字节,然而频繁地访问硬盘上的资源是一个效率比较低的做法,所以需要使用缓冲IO流来对其进行装饰。

使用缓冲IO流进行装饰的代码块:

import java.io.*; /** * @author Fisherman */ public class CopyFIle_Buffered { public static void main(String[] args) throws IOException { File inFile = new File("1.txt"); File outFile = new File("2.txt"); FileInputStream fins = new FileInputStream(inFile); FileOutputStream fouts = new FileOutputStream(outFile); BufferedInputStream bif = new BufferedInputStream(fins); BufferedOutputStream bof = new BufferedOutputStream(fouts); byte[] bytes = new byte[1024];//每次读取的最大数据量为1kb int length; while ((length = bif.read(bytes,0,1024))!=-1){ bof.write(bytes,0,length); } bif.close(); bof.close(); } }三、总结

 Java的IO流操作实际上理解起来很容易,就简单确定输入、输出流的前缀以及后缀,前缀决定的是输入、输出类型,后缀决定read/write方法的参数类型。缓冲IO流我们大可将其视作一块具有能够优化数据所占内存空间大小的“智能”的内存。输出输出流的选择完全可以依靠本文所提到的两张图来完成选择。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3