• IO流


    IO流


    • I:input - 输入(读取),eg:把硬盘的内容读取到内存
    • O: output - 输出(写入) eg:把内存中的东西写入硬盘保存
    • 流:数字(字符/字节) 一般1个字符=2Byte,1Byte = 8bit

    字节流可以读取任意文件:音乐/图片/...,

    • 抛出文件不存在异常,这里统一throws扔给JVm处理,也可以try catch

    字节输出流 -所有字节输出的父类


    • java.io.OutputStream -字节输出流的顶级抽象父类,有以下几种抽象方法

      1. void close()
        关闭此输出流并释放与此流有关的所有系统资源。

      2. void flush()
        刷新此输出流并强制写出所有缓冲的输出字节。

      3. void write(byte[] b)
        将 b.length 个字节从指定的 byte 数组写入此输出流。

      4. void write(byte[] b, int off, int len)
        将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。

      5. abstract void write(int b)
        将指定的字节写入此输出流。

    java.io.FileOutpuStream extends OutputStream


    • FileOutputStream: 文件字节输出流

      1. 作用:把把内存中的东西写入文件

      2. 构造方法:

      FileOutputStream(String name)
      创建一个向具有指定名称的文件中写入数据的输出文件流。

      FileOutputStream(File file)
      创建一个向指定 File 对象表示的文件中写入数据的文件输出流。

      1. FileOutputStream(File file, boolean append)
        append为追加写开关,true为追加写,false为创建一个新文件

      2. 构造方法的作用:

        1. 创建一个FileOutputStream对象
        2. 会根据构造方法中传递的文件/文件路径,创建一个空的文件
        3. 会把FileOutputStream对象指向创建好的文件
    • 数据写入原理(内存->硬盘)

      1. java程序 - JVM虚拟机 - OS - OS调用写数据的方法 - 写入文件
    • 字节输出流的使用步骤

      1. 创建FileOUtputStream对象,并传递写入数据的目的地
      2. 调用FileOutputStream对象中的方法,write方法写入文件中
      3. 流会占用内存,要释放资源
    import java.io.FileOutputStream;
    import java.io.IOException;
    public class IOApi {
        public static void main(String[] args) throws IOException {
    
            //构造方法中绑定要写入数据的目的地
            FileOutputStream output = new FileOutputStream("C:\Users\Administrator\Desktop\java_code\test.txt");
    
            output.write(65);   //十进制65 -> 二进制100 0001‬
            /*
            任意的文本编辑器,在打开文件时都会查询编码表,把字节表示转换
            字符表示
    
            若是0-127,则会查询ASCII表
            其他值:查询系统默认表(中文系统查询JDK编码表)
            即:上文写入A
    
            */
    
            //一次写多个字节
    
            output.close();
        }
    }
    

    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class IOApi {
        public static void main(String[] args) throws IOException {
    
            //使用File生成写入数据目的地,相对路径(不使用File也可以)
            FileOutputStream output = new FileOutputStream(new File("b.txt"));
    
            output.write(49);  //写入三个字节显示为1
            output.write(48);  //写入三个字节显示为0
            output.write(48);  //写入三个字节显示为0
    
            output.close();
        }
    }
    
    
    • 连续写入多个字节,优化上述内容

      1. 如果写的第一个字节是正整数(0-127),那么显示时会查询ASCII码表
      2. 如果写的第一个是负数,那么第一个字节会和第二个字节显示中文字
        符,查询的是系统默认码表(GBK)
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class IOApi {
        public static void main(String[] args) throws IOException {
    
            //使用File生成写入数据目的地,相对路径(不使用File也可以)
            FileOutputStream output = new FileOutputStream(new File("b.txt"));
    
            byte[] bytes ={49,48,48};
    
            output.write(bytes);  //100
    
            byte[] bytes1 ={-56,78,48};
            output.write(bytes1);  //100萅0
    
            //public void write(byte[],int off,int len) :把字节数组的一部分写入到文件中
            //从偏移量off开始输出到此输出流,从指定的字节数组写入len字节
    
            output.write(bytes,1,2);  //100萅000
    
            //String,出现乱码,可能是上面字节与下面字符转换的字节配对
            //写在第一行没问题
            output.write("你好呀".getBytes());  //00萅000浣犲ソ鍛€
            
            output.close();
        }
    }
    
    • 数据的追加与换行
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class IOApi {
        public static void main(String[] args) throws IOException {
    
            //打开追加写开关,false创建新文件,覆盖源文件。
            FileOutputStream output = new FileOutputStream("b.txt",true);
    
            //String
            output.write("你好呀".getBytes());
    
            //Windows: 
    
            //Linux:/n
            //Mac:/r
            output.write("
    好呀".getBytes());
    
            output.close();
        }
    }
    
    

    字节输入流 -所有字节输入的超类


    • java.io.InputStream extends Object 所有子类的部分共性方法:

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

      2. int read(byte[] b)
        从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。

      3. int read(byte[] b, int off, int len)
        将输入流中最多 len 个数据字节读入 byte 数组。

      4. void close()
        关闭此输入流并释放与该流关联的所有系统资源。

    java.io.FileInputStream extends InputStream


    • 作用:将硬盘里的文件读取到内存中

    • 构造方法:

      1. FileInputStream(File file)
        file:数据源
      2. FileInputStream(FileDescriptor fdObj)
        通过使用文件描述符 fdObj 创建一个 FileInputStream,该文件描述符表示到文件系统中某个实际文件的现有连接。
      3. FileInputStream(String name)
        name:文件路径
      • 构造方法的作用:

        1. 会创建一个FileInputSteam对象
        2. 会把FileInputStream对象指定的构造方法中要读取的文件
    • 读取数据原理: java程序 - JVM - OS - 调用OS读取数据的方法 - 读取文件

    • 字节输入流步骤

      1. 创建FileInputStream对象,构造方法中绑定要读取的数据源
      2. 使用FileInputStream的方法read,读取文件
      3. 释放资源
    import java.io.FileInputStream;
    import java.io.IOException;
    
    public class IOApi {
       public static void main(String[] args) throws IOException {
    
           //相对路径获取数据源
           FileInputStream input = new FileInputStream("b.txt");
    
           //使用read方法读取,一次读取一个字节,会返回一个Int值
           System.out.println(input.read());  //239 你
           //读取的第二个值
           System.out.println(input.read());  //187 好
    
           //当input.read返回 -1 时代表读取结束,说明读取到了结束标记
           while(input.read() != -1){
               System.out.println(input.read());
           } 
           
    
           //关闭输入数据流,释放资源
           input.close();
       }
    } 
    
    • 字节输入流一次读入多个字节

    int read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区
    数组 b 中。
    byte[] b:起到缓冲作用,长度一般定义为1024(1kB)或者1024的整数倍
    int:返回值是一个有效字节数

    import java.io.FileInputStream;
    import java.io.IOException;
    import java.util.Arrays;
    
    public class IOApi {
       public static void main(String[] args) throws IOException {
    
           //相对路径获取数据源
           FileInputStream input = new FileInputStream("b.txt");
    
           //连续读,给定一个字节数组,中文字符如果设置的数组不足够长,会有乱码
           //byte[] inp = new byte[10];出现中文乱码,读取不完全
           //数组作用:起到缓冲作用
           byte[] inp = new byte[20];
           
           //read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中,字节数组 b 实际是一个不断重复覆盖的过程
           //input.read(inp)返回的是读取的有效字节的个数
           System.out.println(input.read(inp));  //19
           
           //使用数组工具类转换为码值
           //当数组长度为10时 [-17, -69, -65, -28, -67, -96, -27, -91, -67, -27]
           //当数组长度为20时 [-17, -69, -65, -28, -67, -96, -27, -91, -67, -27, -111, -128, 10, -27, -91, -67, -27, -111, -128, 0]
           System.out.println(Arrays.toString(inp));
    
           /*
           String类的构造方法转换
           String[byte[] bytes] : 把字节数组转换为字符串
           String(byte[] bytes,int offset,int length)把字符数组的一部分转换为字符串,
           offset:偏移位置,length:转换个数
            */
           
           //出现乱码,是因为给的byte[10]长度不够,换为byte[20]正常
           //长度为10 你好� ;长度为20 显示正常
           //主要是idea中用的UTF-8编码,一个中文需要读取三个字节
           System.out.println(new String(inp));
    
           /*********************************************
           为什么要用偏移量0,因为如果数组过大,容易浪费空间
           所以可以设置长度为input.read(inp)的返回值,也就是19,如下
           System.out.println(new String(inp,0,19));
           *********************************************/
    
           //关闭输入数据流,释放资源
           input.close();
       }
    }
    

    文件复制


    • 原理:一读,一写,凡是字节流文件都可以复制
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.Arrays;
    
    public class IOApi {
        public static void main(String[] args) throws IOException {
    
            //读,相对路径获取数据源
            FileInputStream input = new FileInputStream("b.txt");
            byte[] inp = new byte[1024];
            //len为读取的有效字节位数
            int len = input.read(inp);
    
            //写,相对路径给出文件写入抽象位置
            FileOutputStream output = new FileOutputStream("b_copy.txt");
            //给出写入数据,从0开始到有效位置结束
            output.write(inp,0,len);
    
    
    
            //优化代码
            FileInputStream inputJpg = new FileInputStream("C:\Users\Administrator\Pictures\1.jpg");
            FileOutputStream outputJpg = new FileOutputStream("C:\Users\Administrator\Pictures\1_copy.jpg");
            //注,中文结束位会报错,陷入死循环,可复制图片,图片大,用字节数组处理快
            byte[] bytes= new byte[1024*1024];
            int lenJpg = 0;
            while((lenJpg = inputJpg.read(bytes)) != -1){
                outputJpg.write(bytes,0,lenJpg);
            }
    
            //先释放写的,写完一定读完了
            outputJpg.close();
            inputJpg.close();
        }
    }
    
    

    字节流读取中文文件


    • 一个中文:GBK编码占用两个字节 UTF-8:占用三个字节
  • 相关阅读:
    Python基础语法 第2节课(数据类型转换、运算符、字符串)
    python基础语法 第5节课 ( if 、 for )
    python基础语法 第4节课 (字典 元组 集合)
    Python基础语法 第3节课 (列表)
    A. Peter and Snow Blower 解析(思維、幾何)
    C. Dima and Salad 解析(思維、DP)
    D. Serval and Rooted Tree (樹狀DP)
    C2. Balanced Removals (Harder) (幾何、思維)
    B. Two Fairs 解析(思維、DFS、組合)
    D. Bash and a Tough Math Puzzle 解析(線段樹、數論)
  • 原文地址:https://www.cnblogs.com/huxiaobai/p/11575442.html
Copyright © 2020-2023  润新知