最近几天仔细学了Java的io流,本来是打算看视频通过视频来学习的,可是后来发现其实视频看不怎么懂也感觉不是很容易上手,所以就通过百度和api文档学习了Java的io流
io流可以有两个分类,一个是字节流和字符流,另一个是输入流和输出流。
先说说字节流和字符流吧:首先实际上字节流在操作的时候是不会用到缓冲区的,是文件本身的直接操作的,但是字符流在操作的时候下会用到缓冲区的,是通过缓冲区来操作文件的。字节流与字符流的其他区别呢就是读写单位不同,毫无疑问,字符流是以字符为单位,字节流是以字节为单位(一个字节8个bit),由此可知两种的处理对象不同,字节流能处理所有类型的数据,而字符流只能处理字符类型的数据。所以我们可以得到一个结论,那就是只要是处理纯文本数据,就优先考虑使用字符流,除此之外使用字节流。
然后就要说一说输入流和输出流。老实说,从学C语言那时候开始我就输入和输出,output和input很混乱也很不明白。需要不断去接触才更加能够牢记区别吧。输入呢一般是指从外部文件(如硬盘,键盘等)获取数据,而输出呢则是指从程序本身向外部输出数据(如写入文件,显示都屏幕上)。而输入流和输出流还有另一个区别,那就是对输入流只能进行读操作,而对输出流只能进行写操作。
说完这两个大分类,我们可以来了解下其中更详细的一些内容,看看一个类图吧
由继承图看出来,字符输入流Reader是所有的字符输入流的父类。PIpedReader主要是可以通过与其他线程建成的管道读取数据。
而InputStreamReader是一个连接字节流和字符流的桥梁,可以将字节流转变为字符流。
字符输出流Writer是所有的字符输出流的父类。其他子类分别与Reader的各个子类相对应。
输入字节流InputStream是所有的输入字节流的父类。ByteArrayInputStream、StringBufferInputStream、FileInputStream是分别从对应文件读入数据
而PipedInputStream 是从与其它线程共用的管道中读取数据。
输出字节流OutputSteam 是所有的输出字节流的父类。其他分别与InputSteam的子类相互对应。
整个IO类中除了字节流和字符流还包括字节和字符转换流。
OutputStreramWriter将输出的字符流转化为字节流
InputStreamReader将输入的字节流转换为字符流
将字节输出流转化为字符输出流Writer out=new
OutputStreamWriter(
new
FileOutputStream(file));
将字节输入流变为字符输入流Reader read=new
InputStreamReader(
new
FileInputStream(file));
new
InputStreamReader(
new
FileInputStream(file));
那有一个问题,神恶魔时候才要用到转换流呢:当字节和字符之间有转换动作时和流操作的数据需要编码或者解码的时候。
以内容为输出输入目的地,使用内存操作流
ByteArrayInputStream 主要将内容写入内容
ByteArrayOutputStream 主要将内容从内存输出
内容操作流一般使用来生成一些临时信息采用的,这样可以避免删除的麻烦
合并流 SequenceInputStream
SequenceInputStream主要用来将2个流合并在一起,比如将两个txt中的内容合并为另外一个txt。
PushBackInputStream回退流:可以把读取进来的某些数据退回到数据缓冲区
BufferedReader只能接受字符流的缓冲区,因为每一个中文需要占据两个字节,所以需要将System.in这个字节输入流变为字符输入流,采用:
|
比较常用的是采用Scanner类来进行数据输入
Scanner sca =
newScanner(System.in);
// 读一个整数
int
temp = sca.nextInt();
查了下api文档关于scanner的内容发现Scanner的参数代表的是数据从哪里扫描,scanner可以接受任何的输入流
为System.out.println()重定向输出(可以把向控制台输出改为写入文件操作)
System.err重定向 (可以将错误信息写入文件保存)
在流操作中经常需要用到:和\ 不推荐直接用,最好调用两个常量File.separator(\)与File.pathSeparator(:),这样处理的话跨平台操作会比较兼容
如果想在文件中换行的话,需要使用“\r\n”