簡體   English   中英

來自 InputStream 的文件

[英]File from InputStream

是的,這個問題已被問過數百萬次,我相信我已經看過所有這些問題。 它們非常“有時”,緩慢,或者不是我需要的。

在一個項目中,我使用以下代碼使用從 GET 接收到的 InputStream 將其轉換為 PDF。 這每次都在我的物理設備和我的模擬器(Genymotion 2.1.1,Emulator API 18 4.3)上完美運行。 請注意,有些內容被編輯掉了,PDF 通常很小,不到 1 MB。

public abstract class MyPDFFile extends File implements ApiModel{

public MyPDFFile(InputStream inputStream){
    super(context.getExternalFilesDir(
            Environment.DIRECTORY_DOWNLOADS), "my_pdf.pdf");

    if (externalStorageIsWritable()) {
        try {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            FileOutputStream fileInputStream = new FileOutputStream(this);
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(fileInputStream));

            int readLine;
            char[] cbuf = new char[1];

            do {
                readLine = bufferedReader.read(cbuf);
                bufferedWriter.write(cbuf);
            } while (readLine != -1);
            bufferedWriter.close();
        }
        catch(IOException e){
            // Didn't work
        }
    }
    else{
        // Cant write
    }
} 

我想在這個新項目上,我可以使用相同的代碼從互聯網下載 APK 到設備。 不,絕對不是這樣。 我最終為 Inputstream to File 嘗試了這個:

FileOutputStream fileOutputStream = new FileOutputStream(file);

byte[] buffer = new byte[1];
while ( (read(buffer)) > 0 ) {

    fileOutputStream.write(buffer);
}
fileOutputStream.close();
close();

這適用於我的模擬器,並且工作正常。 我開始在我的設備上進行測試......不是那么多,這很奇怪,因為工作 PDF 代碼在我的模擬器和設備上都適用。 我已經嘗試將緩沖區的大小調整為 512 的各種倍數(這導致文件非常小,比如幾 KB,到非常大,大約是 apk 大小的兩倍,大約 5.6 MB)。

另外,另一件奇怪的事情:我永遠無法在構造函數之外成功保存它。 當我在那里保存時,InputStream 很好,我的文件被創建,yadayada,當我使用成功的代碼時,我只是在之后重命名文件,因為我在構造函數中可以訪問的只是 InputStream。 如果我決定“不,我想在我有合適的東西時給它命名”並簡單地將 InputStream 保存到我的對象,它永遠不會正常工作。 下載的文件永遠不能超過 4KB。 我試過extends InputStreamextends BufferedInputStream無濟於事。

如果需要,我可以發布更多代碼。 我所能訪問的只是來自我的 GET 請求的 InputStream; 我正在使用 browep Android HTTP 庫,這就是我可以在不嘗試弄亂庫本身(或覆蓋其中的方法)的情況下獲得的全部內容。

問題是您正在逐字節讀取文件。 這可能需要大量時間。 相反,以更大的塊讀取文件,例如 4 或 8 KB:

int file_chunk_size = 1024 * 4; //4KBs, written like this to easily change it to 8
byte[] buffer = new byte[file_chunk_size];
int bytesRead = 0;
while ( (bytesRead = read(buffer)) > 0 ) {
    fileOutputStream.write(buffer, 0, bytesRead);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM