IO流的基本操作api方法 字符.字节 输入输出的概念

IO流

什么是IO

I input 输入(读取) 硬盘向内存输入数据

O output输出(写入)内存向硬盘写入数据

流:数据 (字节/字符)1个字符=2个字节,1个字节=8个二进制位

IO分类

根据数据的流向分为:输入流和输出流

  • 输入流:就是把数据从其他设备上读取到内存当中.

  • 输出流,就是把数据从内存当中写入到其他设备上的流.

根据数据的类型分为:字节流和字符流

  • 字节流:以字节为单位,读写数据的流

  • 字符流:以字符为单位,读写数据的流

IO流的顶级父类

 输入流输出流
字节流 字节输入流InputStream 字节输出流OutputStream
字符流 字符输入流Reader 字符输出流Writer

字节流

一切皆为字节

一切文件数据(文本文档.图片,视频等)在存储时,都是以二进制数字的形式保存的,都是一个一个的字节,那么数据在进行传输的时候也是如此.所以字节流可以数传任意文件数据.在操作流程的时候,我们要明确,无论使用了什么样的流对象,底层传输的始终为二进制数据.

字节输出流[OutputStream]

java.io.OutputStream此抽象类是表示输出字节流的所有类的超类,将指定的字节信息写入到目的地,它定义了字节输出流的基本共性的api方法:

  • public void close():关闭此输出流并释放与此流相关的其他任何系统资源.

  • public void flush():刷新此输出流并强制任何缓冲的输出字节信息被写入.

  • public void writer(byt[] b):将b.length字节从指定的自节数组写入到此输出流中.

  • public void write(byte b,int off,int len):将指定的字节数组写入len个字节,从偏移量off开始输出到此输出流中

  • public abstract void write(int b):将指定的字节输出到此输出流中.

备注:colose方法,当完成流的操作时,必须调用此方法,释放系统资源.

FileOutputStream类

java.io.FileOutputStream类是文件字节输出流,用于将数据写入到文件中.

构造方法
  • public FilePutStream(File file):创建一个向指定file对象则表示的文件中写入数据的文件输出流.

  • public FilePutStream(String name):创建文件输出流以指定的文件名称写入文件中.

当你创建一个流对象时,必须西安传递一个文件路径,该路径下,如果没有这个文件,会创建该文件,如果有这个文件.会清空这个文件当中的数据,

FilePutOutStream作用:把内存当中的数据写入到硬盘文件中. 构造方法

  - public FilePutStream(File file):创建一个向指定file对象则表示的文件中写入数据的文件输出流.
      - public FilePutStream(String name):创建文件输出流以指定的文件名称写入文件中.
  参数:
        File file:目的地是一个文件
        String name:目的地是一个文件的路径
  构造方法的作用:
        1.创建一个FileOutputStream类对象
        2.会根据构造方法中传递的文件/文件路径(路径上文件不存在),创建一个空的文件.
        3.会把FileOutputStream对象指向创建好的文件.
  字节输出流的使用步骤:
        1.创建一个FileOutPutStream类对象,构造方法中传递写入数据的目的地.
        2.调用FileOutPutStream对象中的write方法.把数据写入到文件中.
        3.释放资源.

 

备注;任何记事本文件在被打开的时候,包括储存方式都是以字节的方式,所以读取的时候采用的是本地字符集,whids系统采用的是GBK.

写入数据的原理:

java成员-->JVM(java)虚拟机-->OS(操作系统)-->OS调用操作系统中的写入数据的方法-->把数据写入到文件中.

示例代码:

//1.创建一个FileOutPutStream类对象,构造方法中传递写入数据的目的地.
       FileOutputStream fos = new FileOutputStream("day28_IO\a.txt");
       //2.调用FileOutPutStream对象中的write方法.把数据写入到文件中.
       fos.write(97);
       //3.释放资源
       fos.close();

UTF-8 一个汉字占三个字节,GBK 一个汉字占两个字节

数据的追加续写

如何在保留目标文件中的数据,还能继续添加新的数据到目标文件中?

  • public FileOutPutStream(File file,boolean append): 创建文件输出流以以写入指定的File对象表示的文件中.

  • public FileOutputStream(String name,boolean append):创建文件输出流以指定的名称写入文件中.

这两个构造方法,参数都需要传入一个boolean类型的值,'true'表示追加数据 , 'false'表示清空原有数据.在这样的情况下创建输出流对象,就可以指定是否需要在文件的末尾添加.

写入换行

Windows系统里面,换行符号是'' '.把以指定是否需要追加续写换行

Linux系统里,换行符号是''/n'

mac系统里,换行符号是'/r'

Unix系统里,每行结尾只有换行,即

回车符 和换行符

  • 回车符:回到一行的开头

  • 换行符:下一行

系统中的换行:

  • Windows系统中,每行结尾是"回车+换行".即 .

  • Unix系统中,每行的结尾只有换行,即

  • Mac系统中,每行的结尾是'回车',即

//1.创建对象
       FileOutputStream fo = new FileOutputStream("day28_IO\c.txt", true);
       //实现数据换行
       fo.write(" ".getBytes());
       //2.调用write()方法
       fo.write("HelloWord".getBytes());
       //3.关闭流对象
       fo.close();

字节输入流

java.io.unputStream此抽象类是表示字节输入流的所有类的超类,可以读取字节信息到内存中,他定义了字节输入流的基本你的共性的api方法

  • public void close():关闭此输入流并释放与此流相关的其他的任何系统资源

  • public abstract int read():从输入流中读取数据的下一个字节.

  • public int read(byte[] b):从输入流中读取一些字节数,并将它们存储到字节数组b当中

备注:close方法,当完成流的相关操作后,需要调用此方法关闭输入流,释放系统资源.

FileInputStream类

java.io.FileInputStream类是文件输入流,从文件中读取字节.

构造方法
  • FileinputStream(Filoe file):通过打开与实际文件的连接来创建一个FileInputStream,该文件有文件系统中的File对象file命名.

  • FileInputStream(String name):通过打开与实际文件的连接来创建一个FileinputStream该文件有文件系统中的路径名name命名. 参数: 读取文件的数据源 String name: 文件的路径 File file: 文件 构造方法的作用有两个: 1.会创建一个FileInputStream类对象 2.会把FileInputStream类对象指定构造方法中要读取的文件 字节输入流的使用步骤: 1.创建一个FileInputStream类对象,构造方法中绑定要读取的数据 2.使用FileInputStream类对象中方法read(),读取文件中的数据 3.释放资源,关闭流对象

当你创建一个流对象时,必须穿入一个文件路径,该路径下,如果没有该文件,会抛出FileNotFoundException异常

使用read()方法读取文件中的字节

int len=0;//表示记录读取到的字节
       while ((len=fi.read())!=-1)
           System.out.print((char)len);

可以使用字符数组来读取数据:read(byte[] b):从输入流中读取多个字节,并且将其存储到缓冲区数组b中,当读取到文件的末尾时,返回一个-1.

代码演示:

int len3=0;//记录读取到的有效字节个数
       byte[] bytes=new byte[1024];//2^10 1024b=1kb
       while ((len3=fr.read(bytes))!=-1){
           //byte[] 转换成String
           //String(byte[]byte,int offset,int length)
         // System.out.println(new String(bytes, 0, len3));
           System.out.println(new String(bytes));
      }

备注:使用数组读取,每次可以读取多个字节,减少了系统间的IO操作次数,从而提高了读取的效率,建议使用.

练习:图片复制

通过字节流实现图片复制

实现从说面的G1.ipeq图片复制到另一个目录下

原理:从已知的文件中读取字节,再把读取到的字节写入到另一个文件中.

      //1.创建一个字节输入流对象FileInputStream,构造方法中绑定需要读取的图片路径
       FileInputStream fi = new FileInputStream("C:\Users\Administrator\Desktop\笔记\Collection接口和Map接口概述.png");
       //2.把文件读取出来
      byte[] bytes = new byte[10240000];
    //   fi.read(bytes);
      //创建字节输出流对象,FileOutPutStream,指向数据复制的目的地文件地址
       FileOutputStream f = new FileOutputStream("day28_IO\c.png");
      //方法1,直接放入整个byte数组
    //   f.write(bytes);
       //方法2
       int len=0;
       while ((len=fi.read(bytes))!=-1){
          f.write(bytes,0,len);
  }
       f.close();
       fi.close();
  }

备注:流的关闭顺序:先开后关,后开先关.

字符流

当使用字节流读取文本文件的时候,肯能会引发一点小问题,如果你遇到中文字符时,可能不会显示完整的字符.拿就是因为一个中文字符可能占用多个字节存储,所以java提供了一些字符流类,以字符为单位读写数据,专门用于处理文本文档文件.

字符输入流[Reader]读取

java.io.Reader抽象类是表示用于读取字符流的所有类的茶类,可以读取字符信息到内存当中,它定义了字符输入流的基本共性的api方法:

  • public void close():关闭此输入流并且释放与此流相关的其他系统资源

  • public int read():从输入流中读取一个字符.

  • public int read(char[] ahuf):从输入流中一次读取多个字符,并将它们存储到字符数组chuf当中.

FileReader类

java.io.FileReader类主要是用于读取字符文件的便捷类.构造方法使用时的编码字符集和默认的字节缓冲区.

备注:

1.字符编码:字节与字符的对应规则.在windows系统中的中文编码默认是GBK,idea中采用UTF-8

2.字节缓冲去:一个自节数组,用来临时存储字节数据.

构造方法

  • FileReader(File file):创建一个新的FileReader对象,给定的指定的需要读取的File对象.

  • FileReader(String filename):创建一个新的FileReader对象,指定需要读取的文件名称.

当你创建一个流对象时,必须闯入一个文件路径,类似于FileinputStream.

 

使用字符数组读取数据:read(char[] chuf),每次读取chuf的长度个字符到数组当中,返回读取到有效字符的个数.当他读取到末尾时,返回-1.

代码实例:

  //创建对象,构造方法中绑定数据源
       FileReader fi = new FileReader("day28_IO\c.txt");
       //2.调用read方法
char[] chuf = new char[1024];
       int len=0;//记录的是每次转换的有效的字符个数
       while ((len=fi.read(chuf))!=-1){
           //字符数组转换成字符串
           //String static valueOf()
           System.out.println(new String(chuf,0,len));
      }
//3.释放资源
fi.colse();

字符输出流[Wruter]

java.io.Writer抽象类是表示用于写入(输出)字符流的所有类的超类.将指定的字符信息写入到目的地中.他同时定义了字符输出流的基本共性的API方法:

  • void write(int c):写入单个字符

  • void write(char[] chuf):写入字符数组

  • abstract void write(char[] chuf,int off,int len):写入char数组的一部分从off(起始索引值)开始,写入len个字符个数.

  • void write(String str):写入字符串.

  • void write(String str,int off,int len):写入字符串的一部分,从字符串的起始索引off开始,写入len个字符

  • void flush():刷新

  • void close():关闭此流,但是需要先刷新它.

FileWriter类

'java.io.FileWriter'类是用于写入字符到文件中,构造方法使用系统默认的字符编码和默认的字节缓冲区.

构造方法

  • FileWriter(File file):创建一个新的FileWriter,指定写入的file对象

  • FileWriter(String name):创建一个新的FileWriter,指定需要写入的文件的名称.

当你创建一个流对象时,必须传入一个文件路径,类似于FileOutputStream.

示例:
    FileWriter fi = new FileWriter("day28_IO\b.txt");
 //2.使用FileWriter赌侠凝重的方法Write.把数据写入到内存缓冲区中(字符转换为字节的过程)
   //void write(int c)写入单个字符
      fi.write(107);//J
 //3.使用FileWriter对象的中的方法flush,把内存缓冲区中的数据刷新到文件中.
  //   fi.flush();
 //4.释放资源(会先把内存缓冲区中的数据刷新到文件中)
       fi.close();

关闭和刷新

因为内置缓冲区的原因,如果不关闭输出流,无法写入字符到文件中.但是关闭流对象,是无法继续写入数据到文件中.如果既想写入数据到文件中,又想继续使用流对象,那么就需要flush方法.

  • flush:刷新缓冲区的数据,流对象可以继续使用

  • close:先刷新缓冲区,然后会通知系统释放资源,关闭流对象,流对象不可以再使用

代码

        //1.创建对象
       FileWriter fi = new FileWriter("day28_IO\e.txt");
       //2.调用write方法.
       fi.write(97);//a
       //3.刷新缓冲区
       fi.flush();//把缓冲区的数据刷新到文件中
       //刷新之后流还可以继续使用
       fi.write(98);
       //4.关闭流对象
       fi.close();
       //close方法之后,流已经关闭了,从内存中消失了,流不能再使用了,如果还用会异常
       //java.io.IOException: Stream closed
       fi.write(99);

写入字符数组:'write(char[] chuf)和write(char[] chuf,int off,ing len)',每次可以写入一个字符数组

用法类似FileOutputSrearm

续写和换行:操作类似于FileOutPutStream

//1.new
       FileWriter fi = new FileWriter("day28_IO\g.txt", true);
       //write
       char[] chars =new char[50];
       for (int i = 0; i < 50; i++) {
           chars[i]=(char)(8140+i);
           fi.write(chars[i]+" ");//
      }
       //flush
       fi.flush();
       //关闭流
       fi.close();

  }

备注:字符流,只能操作文本文件,不能操作图片,视频等非文本文件.

所以当我们单纯的就是想操作文本文件,就是用字符流,其他情况一律使用字节流.

IO异常的处理

JDK1.7之前的处理,
  FileWriter fw=null;
       try {
           //可能会产生异常
       fw = new FileWriter("day28_IO\g.txt", true);
           //2.write
           fw.write(97);
           fw.flush();
      } catch (IOException e) {
           e.printStackTrace();
      }
     //刷新
       finally {
           try {
               fw.close();
          } catch (IOException e) {
               e.printStackTrace();
          }
      }

之后可以把流的操作放入try的小扩号里面 新特性,try后面可以跟进一个小括号,并且放入小括号的流会在try catch结束后自动释放流

在JDK1.7之前使用try...catch...finally 处理流中的异常 格式: try{ //可能会发生的异常 }catch(异常类型 一场变量名){ 异常的处理逻辑}finally{ //释放系统资源 并且finally语句块一定会被执行 }

JDK7新特性

.可以使用try-with-resource语句,该语句确保了每个资源在语句结束时关闭,所谓的资源(resource)是指在程序完成后,必须要关闭的对象.

格式:

try(创建流对象语句,如果多个,请用";"隔开){
   //可能会产生异常的代码
}catch(异常类型 一场变量名){
   //异常处理逻辑
}

代码如下:

 try (    //1.1new
                FileOutputStream fi = new FileOutputStream("day28_IO\g.txt");
                //1.2new
                final FileInputStream fw = new FileInputStream("day28_IO\a.txt"))
      {     //2. write
              int len=0;
              while ((len=fw.read())!=-1){
                  fi.write(len);
      }
      }catch (IOException e){
           //异常的处理逻辑
           e.printStackTrace();
      }
原文地址:https://www.cnblogs.com/rosiness/p/14175812.html