2022Java学习笔记四十九(IO流:写字节数据到文件、文件拷贝、资源释放的方法)

一、文件字节输出流

作用:以内存为基准,把内存中的数据以字节的形式写到磁盘文件中去的

java对字节流转图片 java写字节流到文件_API

java对字节流转图片 java写字节流到文件_java对字节流转图片_02


java对字节流转图片 java写字节流到文件_API_03

实例写入代码

包含知识:
1、写入数据换行
2、如果在有数据的文件后面追加数据,二不是清空再追加
3、关闭写入数据,释放资源
4、中文和换行需要转换成字节

package com.zcl.d4_byte_OutputStream;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;

/*
    目标:字节输出流
 */
public class Demo {
    public static void main(String[] args) throws Exception {
        // 1、创建一个文件字节输出流通道与目标文件接通(不需要自己创建文件,输出文件会自动创建)
        // OutputStream os = new FileOutputStream("file-io-app\\src\\out.text"); // 先清空再追加
        OutputStream os = new FileOutputStream("file-io-app\\src\\out.text",true); // 在文件后面追加数据

        // 2、写数据 write(int a) 写一个字节【写中文会写入成乱码,中文是三个字节】
        os.write(65);
        os.write('a');
        // 换行(需要转换字节)
        os.write("\r\n".getBytes());
        // os.write('中'); 占三个字节,会出现乱码

        // 3、根据字节数组写入数据
        byte[] buffer = {'a',97,98,99};
        os.write(buffer);
        // 换行(需要转换字节)
        os.write("\r\n".getBytes());
        // 如果需要写中文,需要将中文解码成字节
        byte[] buffer2 = "我是中国人".getBytes(StandardCharsets.UTF_8); // 可以指定编码格式
        os.write(buffer2);
        // 换行(需要转换字节)
        os.write("\r\n".getBytes());

        // 4、写一个字节数组的一部分
        byte[] buffer3 = {'a',97,98,99};
        os.write(buffer3,0,3);
        // 换行(需要转换字节)
        os.write("\r\n".getBytes());

        // 写数据必须刷新数据
        // os.flush();
        os.close(); // 释放资源 空出内存空间解除占用 包含刷新【关闭后不能再使用】
    }
}

二、文件拷贝

java对字节流转图片 java写字节流到文件_API_04


文件拷贝案例

需求:把某文件的内容复制到其他目录下
思路:
1、根据数据源创建字节输入流对象
2、根据目标地创建字节输出流对象
3、读写数据,复制内容
4释放资源

实例代码

package com.zcl.d4_byte_OutputStream;

import java.io.*;

/*
    目标:学会字节流拷贝文件(支持一切的字节流文件)
 */
public class CopyDemo {
    public static void main(String[] args) {

        try {
            // 1、创建一个字节输入流管道与文件接通
            InputStream is = new FileInputStream("D:\\黑马2022java学习路线\\第1阶段—Java SE基础\\1、Java基础--20天学会Java\\20天学会java—视频\\day14-常用API(常用API、正则表达式、Lambda、算法)\\day14-常用API(常用API、正则表达式、Lambda、算法)\\01、今日课程介绍.mp4");
            // 2、创建一个输出管道与目标文件接通
            OutputStream os = new FileOutputStream("D:\\abc.mp4");
            // 3、定义一个字节数组转移数据
            byte[] buffer = new byte[1024];
            int len; // 记录转义的字节数
            while ((len = is.read(buffer)) != -1){
                os.write(buffer,0,len);
            }
            System.out.println("数据读取完成");
            // 完成一定要关闭流
            os.close();
            is.close();
        } catch (Exception e) {
            // 拦截预测
            e.printStackTrace();
        }
    }
}

任何文件都适合,拷贝是一字不漏的转移字节,只要前后文件格式、编码一致都没有问题,不适合读取中文的输出

三、资源释放的方式
try-catch-finally

finally:在异常处理时提供finally块来执行所有清除操作,比如说IO流中释放资源
特点:被finally控制的语句最终一定会执行,除非JVM退出

格式代码

package com.zcl.d5_resource;

import java.io.*;

/*
    目标:学会使用finally释放资源
 */
public class TryCatchfinnal {
    public static void main(String[] args) {
        InputStream is = null;
        OutputStream os = null;

        try {
            // 1、创建一个字节输入流管道与文件接通
            is = new FileInputStream("D:\\黑马2022java学习路线\\第1阶段—Java SE基础\\1、Java基础--20天学会Java\\20天学会java—视频\\day14-常用API(常用API、正则表达式、Lambda、算法)\\day14-常用API(常用API、正则表达式、Lambda、算法)\\01、今日课程介绍.mp4");
            // 2、创建一个输出管道与目标文件接通
            os = new FileOutputStream("D:\\abc.mp4");
            // 3、定义一个字节数组转移数据
            byte[] buffer = new byte[1024];
            int len; // 记录转义的字节数
            while ((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
            System.out.println("数据读取完成");
        } catch (Exception e) {
            // 拦截预测
            e.printStackTrace();
        } finally {
            // 无论代码释放正常结束还是异常结束都会执行

            // 完成一定要关闭流
            try {
                // 一定要做非空校验
                if (os != null) os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (is != null) is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

不管代码是否正常或者异常亦或者rteurn都会执行finally中的代码,开发中不建议在finally中加入return返回数据,很容易出现问题

四、简化释放代码

java对字节流转图片 java写字节流到文件_数据_05


JDK7改进方案代码

package com.zcl.d5_resource;

import java.io.*;

/*
    目标:学会使用finally释放资源
 */
public class TryCatchResouceDemo2 {
    public static void main(String[] args) {
        try (
                // 这里面只能存放资源对象,用完会自动关闭:自动调用资源对象的close方法关闭资源(即使出现异常也会关闭操作)

                // 1、创建一个字节输入流管道与文件接通
                InputStream is = new FileInputStream("D:\\黑马2022java学习路线\\第1阶段—Java SE基础\\1、Java基础--20天学会Java\\20天学会java—视频\\day14-常用API(常用API、正则表达式、Lambda、算法)\\day14-常用API(常用API、正则表达式、Lambda、算法)\\01、今日课程介绍.mp4");
                // 2、创建一个输出管道与目标文件接通
                OutputStream os = new FileOutputStream("D:\\abc.mp4");
                //里面自能放资源,其他的数据不能放【实现了Closeable/AutoCloseable接口的类对象】

        ) {
            // 3、定义一个字节数组转移数据
            byte[] buffer = new byte[1024];
            int len; // 记录转义的字节数
            while ((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
            System.out.println("数据读取完成");
        } catch (Exception e) {
            // 拦截预测
            e.printStackTrace();
        }
    }
}