【问题标题】:Android File Copy Confirm for CompletenessAndroid 文件复制确认完整性
【发布时间】:2015-03-01 19:04:19
【问题描述】:

在我的场景中,我使用压缩在资产中的外部只读数据库,并在初始运行时提取/复制到内部存储。

当用户设备的磁盘上没有足够的内存来完成复制时,就会出现此问题。

我会事先检查可用空间,但是当 RAM 不足时,Android 操作系统本身会使用虚拟内存/页面文件,因此可用 MB 的数量不是恒定的。

我想找到一种方法来检查文件本身是否完整,有什么方法可以完成吗?

【问题讨论】:

    标签: android database memory file-copying low-memory


    【解决方案1】:

    检查文件是否一致总是通过检查两个文件的 MD5 哈希是否相互匹配来完成。

    您可以使用 github 上 CyanogenMod ROM 存储库中的此类。这应该可以很好地工作https://github.com/CyanogenMod/android_packages_apps_CMUpdater/blob/cm-10.2/src/com/cyanogenmod/updater/utils/MD5.java

    /*
     * Copyright (C) 2012 The CyanogenMod Project
     *
     * * Licensed under the GNU GPLv2 license
     *
     * The text of the license can be found in the LICENSE file
     * or at https://www.gnu.org/licenses/gpl-2.0.txt
     */
    
    package com.cyanogenmod.updater.utils;
    
    import android.text.TextUtils;
    import android.util.Log;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStream;
    import java.math.BigInteger;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    
    public class MD5 {
        private static final String TAG = "MD5";
    
        public static boolean checkMD5(String md5, File updateFile) {
            if (TextUtils.isEmpty(md5) || updateFile == null) {
                Log.e(TAG, "MD5 string empty or updateFile null");
                return false;
            }
    
            String calculatedDigest = calculateMD5(updateFile);
            if (calculatedDigest == null) {
                Log.e(TAG, "calculatedDigest null");
                return false;
            }
    
            Log.v(TAG, "Calculated digest: " + calculatedDigest);
            Log.v(TAG, "Provided digest: " + md5);
    
            return calculatedDigest.equalsIgnoreCase(md5);
        }
    
        public static String calculateMD5(File updateFile) {
            MessageDigest digest;
            try {
                digest = MessageDigest.getInstance("MD5");
            } catch (NoSuchAlgorithmException e) {
                Log.e(TAG, "Exception while getting digest", e);
                return null;
            }
    
            InputStream is;
            try {
                is = new FileInputStream(updateFile);
            } catch (FileNotFoundException e) {
                Log.e(TAG, "Exception while getting FileInputStream", e);
                return null;
            }
    
            byte[] buffer = new byte[8192];
            int read;
            try {
                while ((read = is.read(buffer)) > 0) {
                    digest.update(buffer, 0, read);
                }
                byte[] md5sum = digest.digest();
                BigInteger bigInt = new BigInteger(1, md5sum);
                String output = bigInt.toString(16);
                // Fill to 32 chars
                output = String.format("%32s", output).replace(' ', '0');
                return output;
            } catch (IOException e) {
                throw new RuntimeException("Unable to process file for MD5", e);
            } finally {
                try {
                    is.close();
                } catch (IOException e) {
                    Log.e(TAG, "Exception on closing MD5 input stream", e);
                }
            }
        }
    }
    

    您应该预先计算文件的 md5 哈希值,然后检查它是否与新传输的文件匹配。

    【讨论】:

      猜你喜欢
      • 2011-03-27
      • 1970-01-01
      • 1970-01-01
      • 2016-04-06
      • 2018-07-28
      • 1970-01-01
      • 2010-11-01
      • 2016-08-21
      • 1970-01-01
      相关资源
      最近更新 更多