RN开发搬砖经验之—分析与定位图片文件被清空的原因

如题

最近工作上处理的一个BUG,先讲下结论/原因,然后再分享该主题相关的东西
结论是:copy图片文件时,源路径与目标路径相同—输入输出流同时操作同一个文件,导致文件清空了!
copy文件的主要源码如下,源代码链接是RNFSManager,JS层调最终调用到的Java方法
在这里插入图片描述

上下文

当前项目需要把应用cache目录下的文件copy至file目录下,然后由于历史代码的原因,导致产生了多次copy调用,同时代码对于copy的文件列表的管理又没有考虑到触发多次copy的情况,那么在底层库的copy方法调用时,导致copy的源文件路径跟目标文件 路径出现相等的情况,最终的结果是文件被清空了-文件size为零,没有内容!

fs库

这里用到了react-native-fs这个库
在这里插入图片描述
最新的版本是2022年,以及上面的RNFSManager中还用着AsyncTask(不是很现代),另外copyFile方法也没有考虑到源文件路径跟目标路径相等的情况!故不推荐大家继续使用该库呢

解决方案

我在项目的解决方案是/在自己的业层逻辑层做处理;
1、避免不产生多次copy文件的操作;
2、在JS层对eact-native-fs的copy方法做一层封装,当源路径与目标路径一样时,向上抛异常;

commons-io

commons-io库也有copy文件的方法,其中是有考虑到源文件路径跟目标路径相等的情况的
在这里插入图片描述

关键点

输入流未关闭的情况下,输出流操作同一路径文件,会造成冲突,输入流会认为该文件不存在并重新创建同名文件覆盖原文件,而后输入流实际读取的是一个空文件,那么输出流写入的内容也为空,最后造成文件内容置空的现象。

我们可以通过下面简单示例代码去验证或作相关的测试实验

package com.company;

import java.io.*;

public class Main {
    private static final String FILE_PATH = "/Users/luogw/Downloads/Gundam-RX-78.jpg";

    public static void printFileSize(String filePath, String tag) {
        File file = new File(filePath);
        System.out.println(String.format("File size: %d bytes, %s", file.length(), tag));
    }

    public static void main(String[] args) {
        try {
            String filepath = FILE_PATH;
            String destPath = FILE_PATH;
            printFileSize(filepath, "刚开始");
            InputStream in = new FileInputStream(filepath);
            printFileSize(destPath, "打开文件输入流");
            OutputStream out = new FileOutputStream(destPath, false);
            //如果是append模式,bug就大了!-循环读取,文件会越来越大!!
//            OutputStream out = new FileOutputStream(destPath, true);
            printFileSize(destPath, "打开文件输出流");

            byte[] buffer = new byte[1024];
            int length;
            while ((length = in.read(buffer)) > 0) {
                System.out.println(String.format("Read %d bytes", length));
                out.write(buffer, 0, length);
            }
            in.close();
            out.close();
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("Error");
        }
    }
}

输出结果
在这里插入图片描述

我们还可以在终端确认下文件的状态
在这里插入图片描述
可以再这样测试一下,把输入流相关的代码去掉!(记得先恢复测试的文件)
在这里插入图片描述
在这里插入图片描述
【关键点】于非append模式创建文件输出流实例时,如果文件已经存在,文件会先被清空!

其它

kimi的建议:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值