• 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:占用三个字节
  • 相关阅读:
    SDN概述
    Linux企业运维人员必备150个命令汇总
    自动化运维工具puppet详解(二)
    自动化运维工具puppet详解(一)
    自动化运维工具[ansible详解三]
    ansible 常用模块
    自动化运维工具【ansible详解 二】
    A. Cinema Line
    A. Wrong Subtraction
    A. The number of positions
  • 原文地址:https://www.cnblogs.com/huxiaobai/p/11575442.html
Copyright © 2020-2023  润新知