簡體   English   中英

從 Java 中的 PHP readfile() 下載 zip 文件

[英]Download a zip file from PHP readfile() in Java

我想通過 HTTP 和 PHP 使用 Java 下載一個 zip 文件。 我需要這個,因為在我讓用戶下載之前我需要 PHP 做一些授權。

授權成功后,頁面使用以下代碼發送文件:

if(file_exists($filename)){

    //Use Content-Disposition: attachment to specify the filename
    header("Content-type: application/zip");
    header('Content-Disposition: attachment; filename='.basename($filename));

    //No cache
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');

    //Define file size
    header('Content-Length: ' . filesize($filename));
    ob_clean();
    flush();
    echo "DOWNLOAD_START\r\n";
    readfile($filename);
    exit;
}else{
    clearstatcache();
    echo "No download available.";
}

通過瀏覽器下載時,下載工作正常。 我通過簡單地嘗試提取它來驗證它是否工作正常。 Java 應用程序生成損壞的版本。

因為頁面也輸出標題信息,所以我回顯 "DOWNLOAD_START\\r\\n" 來表示 zip 文件何時啟動。 下載 ZIP 文件的代碼是:

InputStream sockin = keygenSock.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(sockin));
System.out.println("Reading...");
for(String line = reader.readLine(); line != null; line = reader.readLine()){
    System.out.println(line);
    if(line.startsWith("DOWNLOAD_START")){
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("contents.zip")));
        int read;
        int size = 0;
        byte[] buffer = new byte[2048];
        while((read = sockin.read(buffer, 0, 2048)) >= 0){
            size += read;
            bos.write(buffer, 0, read);
        }
        System.out.println("SIZE READ: " + size);
        bos.flush();
        bos.close();
        //zip(sockin);
        break;
    }
}

讀取的實際字節數不等於實際文件大小(以字節為單位)。 所以我猜我下載 ZIP 文件的方式有問題?

授權后如何讓Java客戶端從頁面下載zip文件?

同樣,錯誤是下載的 ZIP 文件小於實際的 ZIP 文件。

謝謝。

編輯:如果我只是將所有輸出轉儲到 zip 文件中,我可以使用 winRAR 提取它。 但是,如果我在文本編輯器中打開它,我可以在實際 zi​​p 文件之前看到所有標題信息和“DOWNLOAD_START”。 這會導致 Java 解壓縮類(ZipInputStream 和 ZipEntry)失敗,因此即使使用 winRAR 等軟件正確提取,我也不需要包含這些類。

問題在於 BufferedReader,它將讀取/消耗的不僅僅是流中的一行。

所以要么使用無緩沖閱讀器。 這意味着您沒有 readline 方法。

StringBuilder line = new StringBuilder();
int character;
while ((character = reader.read()) >= 0 && character != '\n') {
    line.append(character);
}

或者只是使用 InputStream 做同樣的事情。

StringBuilder line = new StringBuilder();
int character;
while ((character = stream.read()) >= 0 && character != '\n') {
    line.append(character);
}

如果存在,兩行都將包含 \\r (因此相應地更改您的代碼)。 只要使用的編碼不與較低的 127 個字節混淆,無論哪種方式都應該沒問題。

暫無
暫無

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

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