Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android文件拷貝

Android文件拷貝

編輯:關於Android編程

最近項目中協助做了個小的測試程序,需要拷貝文件。代碼如下:

    // fixed for raw data test.
    private static final String RAW_DATA_TEST = "***123***";
    private static final String EXTERNAL_STORAGE = "/mnt/sdcard2";
    private static final String INTERNAL_STORAGE = "/mnt/sdcard";    
    private static final String RAW_DATA_CFG_FILE_NAME = "config.xml";

    // fixed for raw data test.
    static public boolean handleRawDataTest(Context context, String input) {
        if (RAW_DATA_TEST.equals(input)) {
            Log.d(TAG, "handleRawDataTest");

            if (!copyRawDataCfgFile()) {
                Log.d(TAG, "handleRawDataTest, get Raw Data Cfg file failed!");
                Toast.makeText(context, 
                    context.getString(R.string.raw_data_cfg_file_not_exist), 
                    Toast.LENGTH_SHORT).show();
                return false;
            }
            
            Intent intent = new Intent();
            intent.setComponent(new ComponentName("com.goodix.rawdata", 
                                        "com.goodix.rawdata.RawDataTest"));
            context.startActivity(intent);
            return true;
        }
        
        return false;
    }

    public static boolean copyRawDataCfgFile() {
        String state = Environment.getExternalStorageState();
        if (!Environment.MEDIA_MOUNTED.equals(state)) {
            return false;
        }

        String srcFileName = EXTERNAL_STORAGE + File.separator + RAW_DATA_CFG_FILE_NAME;
        String destFileName = INTERNAL_STORAGE + File.separator + RAW_DATA_CFG_FILE_NAME;
        Log.d(TAG, "copyRawDataCfgFile, srcFileName = " + srcFileName + ", destFileName = " + destFileName);
        try {
            if (copyFile(srcFileName, destFileName, true)) {
                Log.d(TAG, "copyRawDataCfgFile, successfull!");
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        Log.d(TAG, "copyRawDataCfgFile, fail!");
        return false;
    }

    public static boolean copyFile(String srcFileName, String destFileName, boolean reWrite) 
        throws IOException {
        Log.d(TAG, "copyFile, begin");
        File srcFile = new File(srcFileName);
        File destFile = new File(destFileName);        
        if(!srcFile.exists()) {
            Log.d(TAG, "copyFile, source file not exist.");
            return false;
        }
        if(!srcFile.isFile()) {
            Log.d(TAG, "copyFile, source file not a file.");
            return false;
        }
        if(!srcFile.canRead()) {
            Log.d(TAG, "copyFile, source file can't read.");
            return false;
        }
        if(destFile.exists() && reWrite){
            Log.d(TAG, "copyFile, before copy File, delete first.");
            destFile.delete();
        }

        try {
            InputStream inStream = new FileInputStream(srcFile);
            FileOutputStream outStream = new FileOutputStream(destFile);
            byte[] buf = new byte[1024];
            int byteRead = 0;
            while ((byteRead = inStream.read(buf)) != -1) {
                outStream.write(buf, 0, byteRead);
            }
            outStream.flush();
            outStream.close();
            inStream.close();
        } catch (IOException e) {
            throw e;
        } catch (Exception e) {
            e.printStackTrace();
        }

        Log.d(TAG, "copyFile, success");
        return true;
    }      
代碼比較簡單,但是中間報了個很奇怪的異常,糾結了很長時間,幸好在臨下班前找到問題根結所在。記下這次事件,以此勉之。

異常如下:

01-01 00:14:31.070: E/StrictMode(3297): A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.
01-01 00:14:31.070: E/StrictMode(3297): java.lang.Throwable: Explicit termination method 'close' not called
01-01 00:14:31.070: E/StrictMode(3297): 	at dalvik.system.CloseGuard.open(CloseGuard.java:184)
01-01 00:14:31.070: E/StrictMode(3297): 	at java.io.FileInputStream.(FileInputStream.java:80)
01-01 00:14:31.070: E/StrictMode(3297): 	at com.android.dialer.SpecialCharSequenceMgr.copyFile(SpecialCharSequenceMgrProxy.java:768)
01-01 00:14:31.070: E/StrictMode(3297): 	at com.android.dialer.SpecialCharSequenceMgr.copyRawDataCfgFile(SpecialCharSequenceMgrProxy.java:702)
01-01 00:14:31.070: E/StrictMode(3297): 	at com.android.dialer.SpecialCharSequenceMgr.handleRawDataTest(SpecialCharSequenceMgrProxy.java:674)
01-01 00:14:31.070: E/StrictMode(3297): 	at com.android.dialer.SpecialCharSequenceMgr.handleCharsForTest(SpecialCharSequenceMgrProxy.java:618)
01-01 00:14:31.070: E/StrictMode(3297): 	at com.android.dialer.SpecialCharSequenceMgr.handleChars(SpecialCharSequenceMgrProxy.java:88)
01-01 00:14:31.070: E/StrictMode(3297): 	at com.android.dialer.dialpad.DialpadFragment.afterTextChanged(DialpadFragment.java:451)
01-01 00:14:31.070: E/StrictMode(3297): 	at android.widget.TextView.sendAfterTextChanged(TextView.java:7626)
01-01 00:14:31.070: E/StrictMode(3297): 	at android.widget.TextView$ChangeWatcher.afterTextChanged(TextView.java:9424)
在網上也搜過“java.io.Closeable for information on avoiding resource leaks”和“java.lang.Throwable: Explicit termination method 'close' not called”,都沒找到和我這個問題類似的情況,一般都是cursor導致的內存洩漏的問題。最終,在反復查看代碼才發現,原來問題的根結在我拷貝文件的目標目錄未指定正確。出現問題的時候,我指定了INTERNAL_STORAGE為“/mnt/sdcard0”,在調用到new FileOutputStream(destFile)時會拋出異常,原因是並沒有這個目錄。手機內部存儲根目錄是“/mnt/sdcard”,這個路徑實際指向了“/storage/sdcard0”。



  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved