Android开发-文件复制粘贴

安卓设备内部文件操作可以使用Android文件操作帮助类FileUtils
注意:
安卓设备若是外接OTG,向外部存储进行文件操作时有时会出现异常。排除权限原因,文件在向OTG进行文件复制粘贴或是删除时,当函数返回成功时,文件有时并未实际写入磁盘,现象就是:向外部设备复制一个文件,当提示文件复制成功时立即拔出OTG,再插上OTG发现刚复制成功的文件损坏,排除Android对OTG热插拔的支持问题。
热插拔OTG,导致刚复制的文件损坏的原因是:文件复制是有缓冲机制的,函数返回复制成功时,文件并未实际落入磁盘,感觉flush()/sync()并未起作用。
解决方法:

  1. 方法1.拔掉OTG,要求安全卸载外部存储设备,执行StorageManager . unmount();
  2. 方法2.使用NDK方式编译so,采用Linux open write 文件写入选择绕过缓冲区 直接写入。此种方法缺点:速度会慢很多,如果有大文件的复制操作(超过500M),等待时间会难以忍受。
    src = open(srcPath, O_RDONLY | O_EXCL);
    dst= open(dstPath, O_RDWR | O_CREAT | O_SYNC | O_DIRECT);
   //源文件设置只读模式,若设置读写模式会导致:正在写的文件无法复制。  
 flag用于指定文件的打开/创建模式,这3个常量定义在fcntl.h中,这3个参数是必选的,而且只能选择一个:
 O_RDONLY      只读模式
 O_WRONLY      只写模式
 O_RDWR        读写模式
 下面的常量是可选的:
 O_DIRECT:     无缓冲的输入、输出。
 O_APPEND      每次写操作都写入文件的末尾。
 O_CREAT       如果指定文件不存在,则创建这个文件。如果存在则直接打开文件。如果创建新文件,而mode参数没有指定,则创建的文件权限不定。
 O_EXCL        如果文件不存在,则返回错误。如果同时指定了O_CREAT,而文件已经存在,则会出错。 用此测试一个文件是否存在,如果不存在,则创建此文件。
 O_TRUNC      如果文件存在,并且以只写/读写方式打开,则清空文件全部内容。
 O_NOCTTY     如果路径名指向终端设备,不要把这个设备用作控制终端。
 O_NONBLOCK   如果路径名指向 FIFO/块文件/字符文件,则把文件的打开和后继 I/O设置为非阻塞模式(nonblocking mode)。
 下面三个标志也是可选的,他们是Single UNIX Specification中同步输入和输出选项的一部分:
 O_DSYNC      等待物理 I/O 结束后再 write。在不影响读取新写入的数据的前提下,不等待文件属性更新。 
 O_RSYNC      read 等待所有写入同一区域的写操作完成后再进行。
 O_SYNC       等待物理 I/O 结束后再 write,包括更新文件属性的 I/O,以同步IO方式打开文件。

具体可参考:
http://blog.csdn.net/zdy0_2004/article/details/51132307 http://blog.csdn.net/hongkangwl/article/details/21338121

使用Android代码进行文件复制需要注意的几点:

  1. 文件复制结束后需要关闭文件流
  2. 文件复制结束后需要flush()
  3. 文件复制结束后需要out.getFD().sync();

以下是FileUtils中部分代码。

/**
     * Copy data from a source stream to destFile.
     * Return true if succeed, return false if failed.
     */
    public static boolean copyToFile(InputStream inputStream, File destFile) {
        try {
            if (destFile.exists()) {
                destFile.delete();
            }
            FileOutputStream out = new FileOutputStream(destFile);
            try {
                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) >= 0) {
                    out.write(buffer, 0, bytesRead);
                }
            } finally {
                out.flush();
                try {
                    out.getFD().sync();
                } catch (IOException e) {
                }
                out.close();
            }
            return true;
        } catch (IOException e) {
            return false;
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值