一、总体结构图

IO流总结 - 图1

二、概念

流是什么:流是一组有顺序的,有起点和终点的字节集合,是对数据传输的抽象,即数据在两设备间的传输称为流。

三、分类

按照处理数据类型的分为:字符流字节流
按照数据流向分为:输入流输出流

1. 字符流和字节流

字节流InputStreamOutputStream是java中可以按照最小字节单位读取的流,即每次读写一个字节,字节流是直接连接到输入源的流。
字符流:是以字符为单位进行数据处理的IO流。本质是基于字节流读取时,去查找指定的码表。

两者的区别:

  1. 读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
  2. 处理对象不同:字节流能处理所有类型的数据(如图片等),而字符流只能处理字符类型的数据。
  3. 字节流:一次读入或读出是8位二进制
  4. 字符流:一次读入或读出是16位二进制
    结论:只要是处理纯文本数据,就优先考虑使用字符流。 除此之外都使用字节流。

2. 输入流和输出流

输入流:只能进行读操作,
输出流:只能进行写操作。

输入字节流 InputStream

  1. InputStream是所有的输入字节流的父类,是一个抽象类。
  2. ByteArrayInputStreamStringBufferInputStreamFileInputStream 是三种基本的介质流,分别从Byte数组StringBuffer、和本地文件中读取数据。
  3. PipedInputStream 是从与其它线程共用的管道中读取数据。
    4.ObjectInputStream 和所有FilterInputStream 的子类都是装饰流(装饰器模式的主角)。
    输出字节流 OutputStream
  4. OutputStream 是所有的输出字节流的父类,是一个抽象类。
  5. ByteArrayOutputStreamFileOutputStream 是两种基本的介质流,它们分别向Byte 数组、和本地文件中写入数据。
  6. PipedOutputStream 是向与其它线程共用的管道中写入数据。
  7. ObjectOutputStream 和所有FilterOutputStream 的子类都是装饰流。
    总结:
    输入流:InputStream或者Reader:从文件中读到程序中;
    输出流:OutputStream或者Writer:从程序中输出到文件中;

3. 节点流

节点流:直接与数据源相连,读入或读出。
直接使用节点流,读写不方便,为了更快的读写文件,才有了处理流。

IO流总结 - 图2

常用的节点流

  1. 父 类 :InputStreamOutputStreamReaderWriter
  2. 文件类型 :FileInputStreamFileOutputStreanFileReaderFileWriter 文件进行处理的节点流
  3. 数组类型 :ByteArrayInputStreamByteArrayOutputStreamCharArrayReaderCharArrayWriter 对数组进行处理的节点流
  4. 字符串 :StringReaderStringWriter 对字符串进行处理的节点流
  5. 管 道 :PipedInputStreamPipedOutputStreamPipedReaderPipedWriter 对管道进行处理的节点流

4. 处理流

IO流总结 - 图3

处理流和节点流一块使用,在节点流的基础上,再套接一层,套接在节点流上的就是处理流。如BufferedReader.处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。

常用的处理流

  1. 缓冲流:BufferedInputStrean 、BufferedOutputStream、 BufferedReader、 BufferedWriter 增加缓冲功能,避免频繁读写硬盘。
  2. 转换流:InputStreamReaderOutputStreamReader实现字节流和字符流之间的转换。
  3. 数据流:DataInputStreamDataOutputStream 等提供将基础数据类型写入到文件中,或者读取出来。
  4. 转换流:InputStreamReaderOutputStreamWriterInputStreamOutputStream作为参数,实现从字节流到字符流的转换。

构造函数

  1. //使用的是本系统默认的编码表GBK。
  2. InputStreamReader(InputStream)
  3. //可指定编码表。
  4. InputStreamReader(InputStream,String charSet)
  5. //使用的是本系统默认的编码表GBK。
  6. OutputStreamWriter(OutputStream)
  7. //可以指定编码表。
  8. OutputStreamwriter(OutputStream,String charSet)

5. ByteArrayInputStream、ByteArrayOutputStream

继承关系

  1. ByteArrayInputStream entends InputStream
  2. ByteArrayOutputStream entends OutputStream

ByteArrayInputStream 可以将字节数组转化为输入流 。
ByteArrayOutputStream可以捕获内存缓冲区的数据,转换成字节数组。

ByteArrayInputStream

构造函数:

  1. public ByteArrayInputStream(byte buf[])
  2. public ByteArrayInputStream(byte buf[], int offset, int length)

常用方法:

  1. // 关闭该流并释放与之关联的所有资源
  2. void close()
  3. //返回此流使用的字符编码的名称
  4. String getEncoding()
  5. //读取单个字符
  6. int read()
  7. //将字符读入数组中的某一部分
  8. int read(char[] cbuf, int offset, int length)
  9. //判断此流是否已经准备好用于读取。
  10. boolean ready()

ByteArrayOutputStream

构造函数

  1. public ByteArrayOutputStream()
  2. public ByteArrayOutputStream(int size)

常用方法

  1. void write(int b)
  2. void write(byte b[], int off, int len)
  3. void writeTo(OutputStream out)
  4. byte toByteArray()[]
  5. void close()

举个栗子

ByteArrayOutputStream读出的字节流用FileOutputStream写入文件

  1. public static void main(String[] args) {
  2. String mes = "helloworld" ;
  3. byte[] b = mes.getBytes() ;
  4. ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream() ;
  5. try {
  6. byteArrayOutputStream.write( b );
  7. FileOutputStream fileOutputStream = new FileOutputStream( new File( "D:/123.txt" ) ) ;
  8. byteArrayOutputStream.writeTo( fileOutputStream ) ;
  9. fileOutputStream.flush();
  10. } catch (FileNotFoundException e) {
  11. e.printStackTrace();
  12. }catch (IOException e) {
  13. e.printStackTrace();
  14. }finally{
  15. try {
  16. byteArrayOutputStream.close();
  17. } catch (IOException e) {
  18. e.printStackTrace();
  19. }
  20. }
  21. }
  22. }

6. File常用方法

创建目录

  1. boolean file.mkdir()

如果创建成功,返回 true , 创建失败,返回false。如果这个文件夹已经存在,则返回false.
只能创建一级目录,如果父目录不存在,返回false.

创建多级目录

  1. boolean file.mkdirs()

创建多级目录,创建成功,返回true,创建失败,返回false。如果父目录不存在,就创建,并且返回true.

创建一个新的文件

  1. boolean file.createNewFile()

如果文件不存在就创建该文件,创建成功,返回 true ;创建失败,返回false。如果这个文件已经存在,则返回false.

判断方法

  1. //文件是否存在
  2. boolean file.exists()
  3. //是否是文件
  4. boolean file.isFile()
  5. //是否是目录
  6. boolean file.isDirectory()
  7. //是否隐藏(windows上可以设置某个文件是否隐藏)
  8. boolean file.isHidden()
  9. //是否为绝对路径
  10. boolean file.isAbsolute()
  11. //是否可读
  12. boolean file.canRead()
  13. //是否可写
  14. boolean file.canWrite()
  15. //是否可执行
  16. boolean file.canExecute()

获取文件的信息

  1. //获取文件的名字
  2. String file.getName()
  3. //获取父目录的绝对路径
  4. String file.getParent()
  5. //获取父文件,返回值是一个File对象
  6. File file.getParentFile()
  7. //返回文件最后一次修改的时间
  8. long time = file.lastModified() ;
  9. Date dt = new Date(time);
  10. //文件命名
  11. boolean renameTo(File file)
  12. //返回文件的大小,单位字节
  13. long file.length()
  14. //删除文件
  15. boolean file.delete()
  16. //获取该目录下的所有的文件的名字
  17. String[] file.list()
  18. //获取该目录下的所有的文件
  19. File[] file.listFiles()

注意:如果file为文件,返回值为null,在使用时记得判空;但是如果file为目录,那么返回这个目录下所有文件的名字,只是名字,不含路径;如果file是一个空目录,返回一个长度为0的数组;list() 方法,只是对file为目录时有效,当file为一个文件的时候,没有意义,listFiles()同理。

7. 栗子

使用FileInputStream类读取文件内容

  1. public static void main(String [] args) throws IOException{
  2. int i=0;
  3. FileInputStream in=null;
  4. try {
  5. //从文件外读数据
  6. in=new FileInputStream("D:\\aaaa.txt");
  7. } catch (FileNotFoundException e) {
  8. // TODO: handle exception
  9. System.out.println("找不到文件");
  10. System.exit(-1);
  11. }
  12. try {
  13. //用于字节个数的计数
  14. int num=0;
  15. while((i=in.read())!=-1){
  16. //将得到的ASCII码值转换成字符型
  17. System.out.println((char)i);
  18. num++;
  19. }
  20. in.close();
  21. System.out.println("传输字节个数:"+num);
  22. } catch (Exception e) {
  23. // TODO: handle exception
  24. System.out.println("读取文件错误");
  25. }
  26. }

使用FileOutputStream写入文件

  1. public static void main(String []args){
  2. int i=0;
  3. FileInputStream in=null;
  4. FileOutputStream out=null;
  5. try {
  6. //实例化FileInputStream,FileOutputStream对象
  7. in=new FileInputStream("D:\\aaaa.txt");
  8. out=new FileOutputStream("D:\\bbbb.txt");
  9. while((i=in.read())!=-1){
  10. out.write(i);
  11. System.out.println((char)i);
  12. }
  13. in.close();
  14. out.close();
  15. System.out.println("文件已复制");
  16. } catch (Exception e) {
  17. // TODO: handle exception
  18. System.out.println("文件复制错误");
  19. System.exit(-1);
  20. }
  21. }