拷贝文件时异常断电导致文件拷贝失败

Android  摘抄  2021年10月25日 pm7:17发布3年前 (2021)更新 城堡大人
148 0 0

前言

测试反馈如果断电前点击收藏歌曲(也就是拷贝到内置存储卡,有提示拷贝成功)后,开机起来后小概率出现部分收藏的歌曲消失了。

原因大概知道,但讲得不够清晰,因此看到网友文章,摘抄于此,方便自己查阅。

真正原因:拷贝文件是写入缓冲区内,调用的flush()也无法保证文件写入到了物理存储设备上。

PS: 本文内容基本摘抄的,感谢网友无私分享。

正文

拷贝代码可以参考《java.io.FileNotFoundException: /storage/** (No such file or directory)》中,这里就不重复了。

分析问题

Linux/Unix系统中,在文件或数据处理过程中一般先放到内存缓冲区中,等到适当的时候再写入磁盘,以提高系统的运行效率。

Android就是一个Linux系统

以下是文件拷贝流程示意图:

拷贝文件时异常断电导致文件拷贝失败

从上面写入文件后,是写入内核缓冲区,至于什么时候写入物理设备,我们是没办法知道的,除非自己主动调用fsync。

也就出现拷贝成功后马上断电导致文件丢失问题了。

解决问题

根据网友提示,解决方式有如下两种方式。

我实际项目中用的是方式一。

拷贝后主动sync
//将数据同步到达物理存储设备
FileDescriptor fd = fileOutputStream.getFD();
fd.sync();
inputStream.close();
fileOutputStream.close();
使用RandomAccessFile 的“rws”模式
  /**
 * asset/DB_NAME_CIYT 拷贝到指定目录
 *
 * @param databasePath
 * @throws IOException
 */
private synchronized void copyDBFile(File databasePath) throws IOException {
    String path = databasePath.getParentFile().getAbsolutePath() + "/";
    Lg.e("dir = " + path);
    File dir = new File(path);
    if(!dir.exists()) dir.mkdirs();
    databasePath.createNewFile();
    InputStream      inputStream      = null;
    RandomAccessFile randomAccessFile = null;
    try {

        inputStream = mContext.getAssets().open(DB_NAME_CIYT);
        //rws模式,会同步到磁盘
        randomAccessFile = new RandomAccessFile(databasePath,"rws");
        byte[] buf   = new byte[1024 * 10];
        int    lenth = 0;
        Lg.e(TAG, "copyDBFile: startCopyDB");
        while ((lenth = inputStream.read(buf)) != -1) {
            randomAccessFile.write(buf, 0, lenth);
        }
        Lg.e(TAG, "copyDBFile: endCopyDB");
        checkoutDB();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (inputStream != null) inputStream.close();
        if (randomAccessFile != null) randomAccessFile.close();
    }
}

参考文章

  1. 拷贝文件时,做完MD5校验,异常断电导致文件拷贝失败

 历史上的今天

  1. 2024: UTF-8下指定字节个数截断字符串(0条评论)
  2. 2023: nginx服务器开启Gzip(0条评论)
  3. 2019: 川端康成:父母的心(0条评论)
  4. 2017: Android的Log等级介绍以及自定义Log工具类(0条评论)
版权声明 1、 本站名称: 笔友城堡
2、 本站网址: https://www.biumall.com/
3、 本站部分文章来源于网络,仅供学习与参考,如有侵权,请留言

暂无评论

暂无评论...

随机推荐

windows下FFmpeg使用以及ffmpeg抽取视频的关键帧

FFmpeg 简介FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。它包括了目前领先的音/视频编码库libavcodec。FFmpeg是在 Linux 下开发出来的,但它可以在包括 Windows 在内的大多数操作系统中编译。这个项目是由 Fabrice ...

Android获取磁盘监听和路径

前言简单记录一监听和获取USB真实路径,记录一下方便自己查阅。系统应用下测试!正文磁盘监听监听磁盘挂载和卸载这个就是Android原生接口广播监听,这个之前有介绍过。IntentFilter intentFilter = new IntentFilter();intentFil...

席慕蓉:无怨的青春

在年轻的时候,如果你爱上了一个人,请你,请你一定要温柔地对待他。不管你们相爱的时间有多长或多短,若你们能始终温柔地相待,那么,所有的时刻都将是一种无瑕的美丽。若不得不分离,也要好好地说声再见,也要在心里存着感谢,感谢他给了你一份记忆。长大了以后,你才会知道,在蓦然回首的刹那,没有怨恨的青春才会...

Android属性动画

前言本文主要介绍Android属性动画。这个是之前看《Android进阶之光》记录的,摘抄于此,方便自己查阅。正文早期Android提供的动画只有帧动画和 View 动画 ,后面Android 3.0后就出现了属性动画。在介绍属性动画前,也重新认识一下View动画的优缺点吧,反正谁好用简单...

[摘]adb 查看系统设置参数

获取系统默认输入法adb shell settings get secure default_input_method更改默认输入法(改为com.sohu.inputmethod.sogouoem/.SogouIME)adb shell settings put secure default_...

PhoneStatusBar启动分析

下面两图让我们大概的了解了SystemUI代码结构和布局范围。 下面是Android SystemUI中包含的各项功能简介,虽然很多,但我这里只是讲解Status Bar,也就是系统上方的状态栏。看第二张图第一部分的顶部部分。Status Bar 系统上方的状态栏Navigator...