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();
        }

    }

}
相关推荐
冰暮流星3 小时前
javascript之数组
java·前端·javascript
Re.不晚3 小时前
JAVA进阶之路——无奖问答挑战3
java·开发语言
代码游侠3 小时前
C语言核心概念复习——C语言基础阶段
linux·开发语言·c++·学习
㓗冽3 小时前
60题之内难题分析
开发语言·c++·算法
dingdingfish3 小时前
Bash学习 - 第3章:Basic Shell Features,第5节:Shell Expansions
开发语言·学习·bash
rainbow68893 小时前
C++开源库dxflib解析DXF文件实战
开发语言·c++·开源
不倒翁玩偶3 小时前
IDEA导入新的SpringBoot项目没有启动按钮
java·spring boot·intellij-idea
deepxuan3 小时前
Day7--python
开发语言·python
小小小米粒4 小时前
Maven Tools
java