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的建议:
在这里插入图片描述

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
rn和flutter都是目前非常流行的移动应用开发框架。 React NativeRN)是Facebook推出的一种开源框架,它运用了Facebook自家的React框架,能够基于JavaScript创建原生的移动应用。RN的优势在于它可以使用一套代码同时在iOS和Android平台上运行,大大减少了开发者的工作量。此外,RN还提供了丰富的组件库和强大的社区支持,使开发者能够快速搭建漂亮、高效的移动应用。 相较之下,Flutter是Google推出的开源框架,它使用Dart语言进行开发。Flutter通过自定义的渲染引擎绘制UI,可以创建高性能且美观的跨平台移动应用。Flutter具有热重载功能,使开发过程更加迅速和便捷。同时,Flutter提供了丰富的组件库和通用的API,使开发者能够轻松创建各种复杂的用户界面。 然而,RN和Flutter也存在一些不同之处。RN使用JavaScript进行开发,而Flutter使用Dart语言,这意味着开发者需要学习不同的编程语言。另外,RN采用的是原生组件的渲染方式,而Flutter则是通过自定义渲染引擎进行绘制。这一差异导致Flutter在性能和用户体验方面更具优势,但对于复杂界面和特定平台功能的需求,RN可能更加灵活。 综上所述,RN和Flutter都是优秀的移动应用开发框架,具有各自的优点和适用场景。开发者可以根据项目需求、个人技能和团队资源来选择适合的框架。无论选择哪个,都能够高效地开发出高质量的移动应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值