JavaIO
JavaIO即Java的输入输出系统。比如我们的程序要读取一个文本文件、一张图片或者要获取控制台输入的内容,就要用到输入流;又或者程序要将生成的一段字符窜以文件的形式保存到系统中就要用到输出等等这些操作。
在Java中与输入和输出相关的类都在Java.io包中。
Java中IO类的组织结构
如下图:
Java IO的类库的框架
Java IO的类库是很庞大的,但是要是理清整体的框架还是可以方便记忆和使用的。
1、从处理的数据类型可以分为:
- 字节流:InputStream和OutputStream
- 字符流:Reader和Writer
字节流直接对文件进行操作;字符流在操作的时候使用了缓冲区(即内存)。
字节流一般用来对媒体文件操作,比如图片;字符流一般可用来操作文本文件,如txt文件。
2、从处理数据的方向(即:是输出文件还是读取文件)可分为:
- 输入流:InputStream和Reader
- 输出流:OutputStream和Writer
输入流是从目标资源将数据输入到程序,比如:将一段字符串从控制台读取到程序;输出流是将数据从程序输出到目标位置,比如:将一段字符串输出到控制台;如下图:
如下表:
字节流 | 字符流 | |
输入流 | InputStream | Reader |
输出流 | OutputStream | Writer |
Java IO中的字节流的使用
如上面的类结构图, InputStream / OuputStream是两个抽像类,不能直接使用,所有的字节流的实现类都直接或者间接的继承了这两个类。比如:FileInputStream / FileOutputStream。
FileInputStream实例:
1 public class FileInputStreamTest { 2 3 4 public static void fileInputStreamTest() { 5 //声明FileInputStream 6 FileInputStream fis=null; 7 try { 8 //在系统的E盘下面有一个temp.txt文件,文件内容是:Hello。 9 String path="E:\\temp.txt";10 //创建FileInputStream对象,将路径作为形参传输入,告诉FileInputStream对象我们要读取哪个文件。11 //当然,这只是一个构造函数,其实还有其他不同的构造函数。12 fis=new FileInputStream(path);13 //使用的是字节流,所以我们使用byte类型的数组来储存读取到的数据。14 byte[] buf=new byte[1024];15 //调用read()方法,将数据读取到的数据保存到buf中。16 //返回值是读取到buf中的byte数量。17 int len=fis.read(buf);18 //将读取的数据输出到控制台19 for(int i=0;i
结果:
hello
FileOutputStream实例:
1 public class FileOutputStreamTest { 2 3 public static void fileOutputStreamTest() { 4 //要输出的内容,这里是65,但是输出到文件的时候会将65转换成ASCII码表中的65对应的字符'A'; 5 byte[] b= {65}; 6 //输出一个文件,在E盘下,文件名为:output.txt 7 String path="E:\\output.txt"; 8 //声明FileOutputStream 9 FileOutputStream fos=null;10 try {11 //实例化FileOutputStream对象12 fos=new FileOutputStream(path);13 //使用write()方法,将b中的数据写到E盘下的output.txt文件。14 fos.write(b);15 }catch(Exception e) {16 17 }18 }20 public static void main(String[] args) {21 //执行22 fileOutputStreamTest();23 }24 25 }
结果:
在E盘下生成一个ouput.txt文件,文件写入一个‘A’字母。
这里我们会发现,如果想要读写字符的话,使用字节流不是很方便,因为还要将字符与编码表中对应的数字一一对应(Java默认编码表是Unicode)。
所以为了方便读写字符,可以使用字符流。而字节流可以用来读写媒体文件,如图片、视频等等。
Java IO中字符流的使用
字符流专门用来操作String字符窜的流,如上类结构图所示,Reader / Writer跟上面的字节流一样也是两个抽象类,所有的字符流都实现了这两个类。比如:FileReader / FileWriter。
FileReader实例:
1 public class FileReaderTest { 2 3 public static void fileReaderTest() { 4 //声明一个Reader 5 Reader r=null; 6 try { 7 //在E盘下面有一个temp.txt文件,文件中有字符:"hello"; 8 String path="E:\\temp.txt"; 9 //实例化FileReader对象10 r=new FileReader(path);11 //cbuf数组用来储存读取到的字符数据。12 char[] cbuf=new char[1024];13 //将读取到的temp.txt中的字符保存在cbuf中14 r.read(cbuf);15 //输出16 System.out.print(new String(cbuf));17 }catch(Exception e) {18 e.printStackTrace();19 }finally {20 //一般在开发中使用io流要记得在不使用的时候关闭,要不会一直占用资源。21 if(r != null) {22 try {23 r.close();24 } catch (IOException e) {25 e.printStackTrace();26 }27 }28 }29 }30 31 public static void main(String[] args) {32 //执行33 fileReaderTest();34 }35 36 }
结果:
控制台输出:hello
FileWriter类实例:
1 public class FileWriterTest { 2 3 public static void fileWriterTest(){ 4 //声明一个FileWriter 5 FileWriter fw=null; 6 try{ 7 //输出内容是output content 8 String str="output content"; 9 //将字符输出到E盘下的output.txt文件下10 String path="E:\\output.txt";11 //实例FileWriter对象,将path作为对象的目标文件。12 fw=new FileWriter(path);13 //使用write方法,把要输出的内容str当作形参传入。14 fw.write(str);15 //执行完write后,这是并没有将字符输出。如果此时在在这里打端点,会发现并没有输出内容。16 //执行flush后,才会将字符串输出。或者在流关闭的时候,也会将字符串输出。17 fw.flush();18 }catch(Exception e) {19 e.printStackTrace();20 }finally {21 //关闭流,否则会占用资源。22 if(fw != null) {23 try {24 fw.close();25 } catch (IOException e) {26 e.printStackTrace();27 }28 }29 }30 }31 32 33 public static void main(String[] args) {34 //执行35 fileWriterTest();36 }37 }
在实际编程中,一般的输入输出流(或者说字符流和字节流)都应该在不再使用的时候执行close()方法关闭。
但在java7只有,可以在try()的括号中实例化流,这样,即使不使用close(),程序也会在最后自动的关闭流对象。
其他的实现类
- 转换流:InputStreamReader / OutputStreamReader。
这两个类实现了Reader抽象类,这两个类是字符流和字节流之间的转换桥梁。这两个类可以将字节流转换成字符流。用法与上面相似
- 缓冲流:BufferedReader / BufferedWriter , BufferedInputStream /BufferedOuputStream。
这些类是会将数据首先缓存起来然后再执行操作。比如:BufferedInputStream会将读取的的数据保存在缓存(内存)中,然后从缓存中读取,就不需要每次一点点的执行读取操作,这样如果读取很多数据的话,效率就会更高,因为从内存中读取数据要比从硬盘中读取数据快很多。;
BufferedOuputStream会把要输出的数据存到缓存中,在需要的时候才将数据输出。
参考链接:、、