亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

復制的文檔文件與原始文檔文件的大小和哈希值不同

復制的文檔文件與原始文檔文件的大小和哈希值不同

拉丁的傳說 2023-09-27 14:49:06
我正在嘗試在 Android 應用程序中復制/復制 DocumentFile,但在檢查創建的副本時,它似乎與原始文件并不完全相同(這導致了問題,因為我需要對文件進行 MD5 檢查)下次調用副本時這兩個文件,以避免覆蓋相同的文件)。流程如下:用戶從 ACTION_OPEN_DOCUMENT_TREE 選擇文件獲取源文件類型目標位置的新文檔文件已初始化第一個文件的內容復制到第二個文件中初始階段通過以下代碼完成:// Get the source file's typeString sourceFileType = MimeTypeMap.getSingleton().getExtensionFromMimeType(contextRef.getContentResolver().getType(file.getUri()));// Create the new (empty) fileDocumentFile newFile = targetLocation.createFile(sourceFileType, file.getName());// Copy the fileCopyBufferedFile(new BufferedInputStream(contextRef.getContentResolver().openInputStream(file.getUri())), new BufferedOutputStream(contextRef.getContentResolver().openOutputStream(newFile.getUri())));主要復制過程是使用以下代碼片段完成的:    void CopyBufferedFile(BufferedInputStream bufferedInputStream, BufferedOutputStream bufferedOutputStream)    {        // Duplicate the contents of the temporary local File to the DocumentFile        try        {            byte[] buf = new byte[1024];            bufferedInputStream.read(buf);            do            {                bufferedOutputStream.write(buf);            }            while(bufferedInputStream.read(buf) != -1);        }        catch (IOException e)        {            e.printStackTrace();        }        finally        {            try            {                if (bufferedInputStream != null) bufferedInputStream.close();                if (bufferedOutputStream != null) bufferedOutputStream.close();            }            catch (IOException e)            {                e.printStackTrace();            }        }    }我面臨的問題是,雖然文件復制成功并且可用(它是一張貓的圖片,并且在目的地仍然是一張貓的圖片),但它略有不同。文件大小已從 2261840 更改為 2262016 (+176)MD5 哈希值已完全改變我的復制代碼是否有問題導致文件略有更改?提前致謝。
查看完整描述

1 回答

?
狐的傳說

TA貢獻1804條經驗 獲得超3個贊

您復制的代碼不正確。它假設(錯誤地)每次調用read都會返回buffer.lengthbytes 或 return -1。


您應該做的是捕獲每次在變量中讀取的字節數,然后準確寫入該字節數。您用于關閉流的代碼很冗長并且(理論上1)也有錯誤。


這是解決這兩個問題以及其他一些問題的重寫。


void copyBufferedFile(BufferedInputStream bufferedInputStream,

? ? ? ? ? ? ? ? ? ? ? BufferedOutputStream bufferedOutputStream)

? ? ? ? ?throws IOException?

{

? ? try (BufferedInputStream in = bufferedInputStream;

? ? ? ? ?BufferedOutputStream out = bufferedOutputStream)?

? ? {

? ? ? ? byte[] buf = new byte[1024];

? ? ? ? int nosRead;

? ? ? ? while ((nosRead = in.read(buf)) != -1)? // read this carefully ...

? ? ? ? {

? ? ? ? ? ? out.write(buf, 0, nosRead);

? ? ? ? }

? ? }

}

正如您所看到的,我已經擺脫了虛假的“捕獲和擠壓異常”處理程序,并使用 Java 7+?try with resources修復了資源泄漏。

仍然存在幾個問題:

  1. 復制函數最好將文件名字符串(或File對象Path)作為參數并負責打開流。

  2. 鑒于您正在執行塊讀取和寫入,因此使用緩沖流沒有什么價值。(事實上,它可能會使 I/O 變慢。)最好使用普通流并使緩沖區的大小與類使用的默認緩沖區大小相同或Buffered*更大。

1 - 理論上,如果拋出bufferedInputStream.close()異常,bufferedOutputStream.close()調用將被跳過。實際上,關閉輸入流不太可能引發異常。但無論哪種方式,嘗試資源方法都會正確且更加簡潔地處理這個問題。


查看完整回答
反對 回復 2023-09-27
  • 1 回答
  • 0 關注
  • 174 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號