IO流~~

IO流解决程序中的什么问题?

  • 把程序中存储在内存中的数据,写入到文件中(持久存储)
  • 把磁盘文件中存储的数据,读取到内存中(Java程序)

IO流:

  • I流: 把磁盘文件中存储的数据,读取到内存中(读数据)
  • O流:把内存中的数据,写入到磁盘文件(写数据)

InputStream:输入流

  • 字节输入流
  • 字符输入流

OutputStream:输出流

  • 字节输出流
  • 字符输出流

字节流:万能流(所有类型的文件都可以读写)

字符流:通常用于针对纯文本文件进行读写操作

  • 纯文本文件: 使用计算机中的记事本软件打开并看得懂的文件

IO流的作用:对磁盘上的文件进行读、写操作

  • 读:输入流
  • 写:输出流(把内存中的数据写入到磁盘文件中)

学习所有的IO流有一个固定套路:

第1步:创建

  • 实例化不同的IO流类

第2步:操作(写、读)

  • 读:read()
  • 写:write()

第3步:关闭

  • close()

字节输出流

字节输出流:以字节为单位,把内存中数据写入到磁盘文件中

步骤:

1.创建字节输出流对象。注意:如果文件不存在,就创建;如果文件存在就清空

2.写数据。注意:写出的整数,实际写出的是整数在码表上对应的字符

3.释放资源。注意:每次使用完流必须要释放资源

三种方式:

java 复制代码
void write(int a)  一次写一个字节数据
void write(byte[] a)  一次写一个字节数组数据
void write(byte[] a, int off, int len)  一次写一个字节数组的部分数据
java 复制代码
import java.io.*;


public class OutputStreamDemo1 {
    //字节输出流
    public static void main(String[] args) throws IOException {
        //创建字节输出流对象
        OutputStream os = new FileOutputStream("files/hello.txt");
        //操作:写数据
        os.write('B');//char类型在底层自动转换为int,通过码表
        //关闭
        os.close();
    }
}
java 复制代码
import java.io.FileOutputStream;
import java.io.IOException;

public class OutputStreamDemo2 {
    public static void main(String[] args) throws IOException {
        //创建字节输出流
        FileOutputStream os = new FileOutputStream("files/helloworld.txt");

        //操作:写数据
       // os.write("嗨,你好呀".getBytes());//把字符串转换为字节数据并存储到数组中

        byte[] buf = "haihai".getBytes();
        os.write(buf,1, 5);//将字节数组中部分数据,写入到文件中
        //释放资源
        os.close();
    }
}

向文件中追加写入数据:(创建字节输出流对象时,不会清空文件中的原有内容)

java 复制代码
FileOutputStream fos = new FileOutputStream("关联文件" , true );
//第二个参数: true , 表示追加写入数据

向文件中写入:换行符号

java 复制代码
fos.write("\r\n".getBytes());
java 复制代码
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class OutputStreamDemo3 {
    public static void main(String[] args) throws IOException {
        //创建字节输出流对象,并关联文件,表示追加写入
        FileOutputStream fos = new FileOutputStream("files/hello.txt",true);
        //输出内容
        fos.write("hello,nihao".getBytes());
        //换行
        fos.write("\r\n".getBytes());
        //关闭资源
        fos.close();
    }
}

字节输入流

InputStream(抽象类)

  • FileInputStream类(使用到的)

步骤:

1.创建字节输出流对象。注意:如果文件不存在,就直接报错

2.读数据。注意:读出来的是文件中数据的码表值

3.释放资源。注意:每次使用完流必须要释放资源

java 复制代码
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

public class InputStreamDemo1 {
    public static void main(String[] args) throws IOException {
        //创:创建字节输入流对象,并关联文件
        //InputStream is = new FileInputStream("files/test.txt");//当关联的文件不存在时:运行时异常
        InputStream is = new FileInputStream("files/hello.txt");

        //读:读取数据
//        int ch = is.read();//读取到A的编码值:97
        char ch = (char)is.read();//读取到A的编码值:97,强制转换为char类型
        System.out.println(ch);//A

        char ch1 = (char)is.read();
        System.out.println(ch1);//B

        char ch2 = (char)is.read();
        System.out.println(ch2);//C

        int ch3 = is.read();//读到文件末尾了,(没有数据了)
        System.out.println(ch3);


        //关:释放资源
        is.close();
    }
}

文件拷贝案例

文件复制方案:

  • 前置:
    • 有源文件(读源文件中的数据)
    • 有目标文件(向目标文件中写入数据)
  1. 创建字节输入流,关联源文件
  2. 创建字节输出流,关联目标文件
  3. 使用字节输入流,读取源文件中的字节数据
  4. 把读取到的字节数据,写入到目标文件中
  5. 循环重复:3、4
  6. 当源文件读取结束( 结束标记:-1 )
  7. 释放资源
java 复制代码
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyFile1{
    public static void main(String[] args) throws IOException {
        //创建字节输入流,关联源文件(读)
        FileInputStream fis = new FileInputStream("C:\\Users\\韦爽\\Documents\\code\\123.jpg");

        //创建字节输出流,关联目标文件(写)
        FileOutputStream fos = new FileOutputStream("files/images.jpg");

        //循环:读数据,写数据
        int data = 0;
        while((data = fis.read()) != -1){
            //把读取的数据写入到目标文件中
            fos.write(data);
        }

        //释放资源
        fis.close();
        fos.close();
    }
}

IO资源处理

try...catch升级版

java 复制代码
try{
    
    //监视可能会发生异常的代码
    
}catch(Exception e){
    
    //处理异常
    
}finally{
    
    //不论是否有异常,都会执行
    //应用场景: 释放资源
    
}
java 复制代码
有点繁琐
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyFile1 {
    public static void main(String[] args){
        FileInputStream fis = null;
        FileOutputStream fos = null;
        //创建字节输入流,关联源文件(读)
        try {
            fis = new FileInputStream("C:\\Users\\韦爽\\Documents\\code\\123.jpg");

            //创建字节输出流,关联目标文件(写)
            fos = new FileOutputStream("files/images.jpg");

            //循环:读数据,写数据
            int data = 0;
            while ((data = fis.read()) != -1) {
                //把读取的数据写入到目标文件中
                fos.write(data);
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            //释放资源
            try{
                if(fos!=null){
                    fos.close();
                }
                if(fis!=null){
                    fis.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }
}

升级版:

JDK1.7版本中IO资源处理代码:

  • 好处:自动释放IO资源 ( 不需要在书写close方法 )
    • 资源对象想要实现自动释放,必须保证资源对象有实现AutoCloseable接口
java 复制代码
try( IO流对象; IO流对象; ... ){
    
    //监视可能会发生异常的代码
    
}catch(Exception e){
    
    //处理异常
    
}
java 复制代码
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyFile2 {
    public static void main(String[] args){
        //创建字节输入流,关联源文件(读)  //创建字节输出流,关联目标文件(写)

        try(FileInputStream fis = new FileInputStream("C:\\Users\\韦爽\\Documents\\code\\123.jpg");
            FileOutputStream fos = new FileOutputStream("files/images.jpg");
        ) {
            //循环:读数据,写数据
            int data = 0;
            while ((data = fis.read()) != -1) {
                //把读取的数据写入到目标文件中
                fos.write(data);
            }
        }catch (IOException e){
            //异常处理
            e.printStackTrace();
        }

//        不用再释放资源
//        fis.close();
//        fos.close();
    }

}

文件复制:

  • 方案1:循环一次读写1个字节数据 (程序性能低)
  • 方案2:循环一次读写多个字节数据(性能高)
java 复制代码
//一次读取1个字节数据,返回实际读取到的字节数据;读取到文件末尾时返回:-1
int  read()  
    
    
//一次最多读取buf.length个字节数据,把读取到的字节数据存储到buf数组中,并返回实际读取字节数据的个数
//读取到文件末尾时返回:-1
int  read(byte[] buf)    

提升性能

一次读取多个数据
java 复制代码
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;

public class InputStreamDemo2 {
    //read(byte[] buf)方法使用
    public static void main(String[] args) throws IOException {
        //创建字节输出流
        FileInputStream fis = new FileInputStream("files/helloworld.txt");

        //定义字节数组
        byte[] buf = new byte[5];
        //第一次读取数据
        int len = fis.read(buf);
        System.out.println("第一次读取数据个数:"+len);//第一次读取数据个数:5
        System.out.println("数据为:"+ Arrays.toString(buf));//数据为:[104, 101, 108, 108, 111]
        System.out.println(new String(buf,0,len));//hello

        //第二次读取数据
        len = fis.read(buf);
        System.out.println("第二次读取数据:"+ len );//第二次读取数据:5
        System.out.println("数据为:"+ Arrays.toString(buf));//数据为:[119, 111, 114, 108, 100]
        System.out.println(new String(buf,0,len));//world
        //第三次读取数据
        len = fis.read(buf);
        System.out.println("第三次读取数据:"+ len );//第三次读取数据:1
        System.out.println("数据为:"+ Arrays.toString(buf));//数据为:[126, 111, 114, 108, 100]
        System.out.println(new String(buf,0,len));//~
        //关闭资源
        fis.close();
    }
}
java 复制代码
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyFile2 {
    /*文件复制:
     *    需要源文件: 使用字节输入流读文件数据
     *    需要目标文件: 使用字节输出流向文件中写入数据
     * */

    public static void main(String[] args) {
        String srcPath = "f:/files/111.jpg";
        String destPath = "files/111.jpg";  //必须是目标文件,而不是目标目录

        long beginTime = System.currentTimeMillis();
        copy(srcPath, destPath);
        long endTime = System.currentTimeMillis();

        System.out.println("文件复制花费:" + (endTime - beginTime) + "毫秒");//6毫秒
    }

    /**
     * 文件复制 :读多个个字节数据,写入多个个字节数据
     *
     * @param src  源文件路径
     * @param dest 目标文件路径
     */
    public static void copy(String src, String dest) {
        //循环:读取源文件中的数据,向目标文件中写入数据
        //字节输入流,并联源文件
        //字节输出流,并联目标文件
        try (FileInputStream fis = new FileInputStream(src);
             FileOutputStream fos = new FileOutputStream(dest);
        ) {
            //字节数组
            byte[] buf = new byte[1024*8]; //一次读取1K
            //读取字节数据的个数
            int len = -1;

            while ((len = fis.read(buf)) != -1) {
                //向目标文件中写入实际读取到的字节数据
                fos.write(buf, 0, len);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

在IO体系下,java提供了高效流(提高读写文件的效率)

  • 读文件:BufferedInputStream
  • 写文件:BufferedOutputStream

BufferedInputStream流的创建: 读数据

  • 自己没有读数据的能力,需要依赖字节输入流实现读数据
java 复制代码
//构造方法: public  BufferedInputStream( InputStream  is )

BufferedInputStream bis = new BufferedInputStream( new FileInputStream("关联文件") );

BufferedOutputStream流的创建: 写数据

  • 自己没有写数据的能力,需要依赖字节输出流实现读数据
java 复制代码
//构造方法: public  BufferedOutputStream( OutputStream  os )

//覆盖写入
BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream("关联文件") );


//追加写入 (构造方法的第二个参数为true)
FileOutputStream fos = new FileOutputStream("关联文件" , true); //追加写入
BufferedOutputStream bos = new BufferedOutputStream(  fos );//当前流有具有追加写入能力

使用字节缓冲流提高效率

java 复制代码
import java.io.*;

public class CopyFile {
    public static void main(String[] args) {
        String srcPath = "C:\\Users\\韦爽\\Documents\\code\\123.jpg";
        String destPath = "files/images.jpg";  //必须是目标文件,而不是目标目录

        long beginTime = System.currentTimeMillis();
        copy(srcPath, destPath);
        long endTime = System.currentTimeMillis();

        System.out.println("文件复制花费:" + (endTime - beginTime) + "毫秒");//6毫秒
    }

    /**
     * 文件复制 :使用高效流(缓冲流)提高读写能力
     *
     * @param src  源文件路径
     * @param dest 目标文件路径
     */
    public static void copy(String src, String dest) {
        //循环:读取源文件中的数据,向目标文件中写入数据
        //字节输入流,并联源文件
        //字节输出流,并联目标文件
        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src));
             BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dest));

        ) {
            //字节数组
            byte[] buf = new byte[1024*8]; //一次读取1K
            //读取字节数据的个数
            int len = -1;

            while ((len = bis.read(buf)) != -1) {
                //向目标文件中写入实际读取到的字节数据
                bos.write(buf, 0, len);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}
相关推荐
Scott9999HH8 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
腻害兔8 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
码智社9 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海9 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖10 小时前
JDK 26 新特性详解
java·开发语言
马优晨10 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区12 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大13 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai13 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
维天说13 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json