1.8 IO字节流

概述

输入输出

  • 输入流 :把数据从 其他设备 上读取到 内存 中的流。
  • 输出流 :把数据从 内存 中写出到 其他设备 上的流。

字节流

  • 一切皆为字节,字节流可以传输任意数据

字节输出流(OutputStream)(内存->硬盘)

  • java.io.OutputStream:此抽象类是表示字节输出流的所有类的超类;
  • 定义了一些子类共性的成员方法:

public void close():关闭此输出流并释放与此流相关联的任何系统资源。
public void flush():刷新此输出流并强制任何缓冲的输出字节被写出。 、
public void write(byte[] b) :将 b.length字节从指定的字节数组写入此输出流。
public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输 出到此输出流。
public abstract void write(int b) :将指定的字节输出流。

FileOutputStream类(文件字节输出流)

构造方法

  • public FileOutputStream(File file) :创建文件输出流以写入由指定的 File对象表示的文件。
  • public FileOutputStream(String name): 创建文件输出流以指定的名称写入文件。
  • 当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有这个文件,会创建该文件。如果有这个文 件,会清空这个文件的数据

使用

  • 写入数据原理:

java程序—>JVM虚拟机—>OS操作系统—>OS调用写数据的方法—>把数据写入到文件中

  • 使用步骤
  1. 创建FileOutputStream对象,构造方法中传递写入数据的目的地
  2. 调用write方法写入数据
  3. 关闭流
//使用 write(int b)一次写一个字节
public class FosWrite{
   public static void main(String[] args) throws IOException {         
   // 使用文件名称创建流对象         
   FileOutputStream fos = new FileOutputStream("fos.txt");             
   // 写出数据           
   fos.write(97); // 写出第1个字节           
   fos.write(98); // 写出第2个字节           
   fos.write(99); // 写出第3个字节           
   // 关闭资源            
   fos.close();     
   } 
 } 
   输出结果: abc
  • 注意:虽然参数为int类型四个字节,但是只会保留一个字节的信息写出。
//使用 write(byte[] b) 一次写多个字节
public class FOSWrite {     
   public static void main(String[] args) throws IOException {         
   // 使用文件名称创建流对象         
   FileOutputStream fos = new FileOutputStream("fos.txt");             
   // 字符串转换为字节数组           
   byte[] b = {65,66,67,68,69}    //输出结果: ABCDE
   byte[] b = {-65,-66,-67,68,69}  //输出结果:烤炴E  
   byte[] b = "你好".getBytes();  //输出结果:你好    
   // 写出字节数组数据           
   fos.write(b);           
   // 关闭资源            
   fos.close();     
   } 
} 
  • 注意:一次写多个字节
  1. 如果写的第一个字节是正数(0~127),那么显示的时候会查询ASCII表
  2. 如果写的第一个字节是负数,那么第一个字节会和第二个字节,两个字节组成一个中文显示,查询系统默认码表(GBK)

文件存储原理和记事本打开原理

  • 硬盘中存储的都是字节,1字节=8个二进制位
  • 在任意的文本编辑器中打开文件时,都会查询编码表,将字节转化为字符表示
    0~127:查询ASCII码表
    其它值:查询系统默认码表(中文系统GBK)

文件存储和打开原理

数据的追加续写和换行写

追加续写
  • 每次程序运行,创建输出流对象,都会清空目标文件中的数据(删除该文件,创建新的空文件)。如何保留目标文件中数据,还能继续添加新数据呢?
  • public FileOutputStream(File file, boolean append) : 创建文件输出流以写入由指定的 File对象表示的 文件。
  • public FileOutputStream(String name, boolean append) : 创建文件输出流以指定的名称写入文件。
  • true 表示追加数据, false 表示清空原有数据。
换行
  • windows:\r\n

    回车符 \r和换行符\n
    回车符:回到一行的开头(return)。
    换行符:下一行(newline)。

  • linux:/n
  • mac:/r
public class FOSWrite {     
    public static void main(String[] args) throws IOException {         
        // 使用文件名称创建流对象         
        FileOutputStream fos = new FileOutputStream("fos.txt");          
        // 定义字节数组           
        byte[] words = {97,98,99,100,101};           
        // 遍历数组            
        for (int i = 0; i < words.length; i++) {            
        // 写出一个字节                
        fos.write(words[i]);            
        // 写出一个换行, 换行符号转成数组写出                
        fos.write("\r\n".getBytes());         
       }        
       // 关闭资源            
       fos.close();     
       } 
   }

字节输入流(InputStream)(硬盘->内存)

  • java.io.InputStream 抽象类是表示字节输入流的所有类的超类
  • 字节输入 流的基本共性功能方法:

public void close():关闭此输入流并释放与此流相关联的任何系统资源。
public abstract int read(): 从输入流读取数据的下一个字节。
public int read(byte[] b): 从输入流中读取一些字节数,并将它们存储到字节数组 b中 。

FileInputStream类

  • java.io.FileInputStream类是文件输入流,从文件中读取字节。
  • 读取数据原理

java程序—>JVM虚拟机—>OS操作系统—>OS调用读取数据的方法—>读取文件

构造方法

  • FileInputStream(File file): 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
  • FileInputStream(String name): 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。
  • 当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有该文件,会抛出FileNotFoundException

使用

  • 使用步骤:
  1. 创建FileInputStream对象,构造方法中传递写入数据的目的地
  2. 调用read方法读取文件
  3. 关闭流
  • 读取字节: read 方法,每次可以读取一个字节的数据,提升为int类型,读取到文件末尾,返回 -1 ;
一次读取一个字节
public class FISRead {     
    public static void main(String[] args) throws IOException{        
        // 使用文件名称创建流对象            
        FileInputStream fis = new FileInputStream("read.txt");  //abc        
        // 读取数据,返回一个字节            
        /*int read = fis.read();         
        System.out.println((char) read); //a        
        read = fis.read();         
        System.out.println((char) read);  //b              r
        read = fis.read();         
        System.out.println((char) read);   //c     
        // 读取到末尾,返回‐1            
        read = fis.read();           
        System.out.println( read); */
        int len=0;
        while((len=fis.read())!=-1){
           System.out.println((char) len); 
        }
        // 关闭资源                  
        fis.close();     
        } 
     }
字节流一次读取一个字节的原理

读取原理

一次读取多个字节原理

读取多个字节原理

  • 从图中可以看出,第一次(AB)和第二次(CD)输出结果正确,第三次(ED)和第四次(ED)输出错误,第三次应该只输出E,第四次无输出,这是因为在bytes数组中,上次读取的数据没有被完全替换;
public class FISRead {     
   public static void main(String[] args) throws IOException{        
      // 使用文件名称创建流对象.            
      FileInputStream fis = new FileInputStream("read.txt"); // 文件中为abcde          
      // 定义变量,作为有效个数            
      int len ;     
      // 定义字节数组,作为装字节数据的容器            
      byte[] b = new byte[2];         
      // 循环读取         
      while (( len= fis.read(b))!=1) {             
      // 每次读取后,把数组的有效字节部分,变成字符串打印               
      System.out.println(new String(b,0,len));//  len 每次读取的有效字节个数         
      } 
      // 关闭资源                  
      fis.close();     
      } 
 }   
 输出结果: 
 ab 
 cd 
 e

字节流读取中文问题

  • 使用字节流读取中文文件

1个中文
   GBK:占用两个字节
   UTF-8:占用三个字节

  • 当使用字节流读取文本文件时,可能会有一个小问题。就是遇到中文字符时,可能不会显示完整的字符,那是因为 一个中文字符可能占用多个字节存储,而一次只能读取一个字节,从而产生乱码问题。所以Java提供一些字符流类,以字符为单位读写数据,专门用于处理文本文 件。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值