Zip文件在接收时损坏

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Zip文件在接收时损坏相关的知识,希望对你有一定的参考价值。

我有一个生成zip文件的php脚本。

生成的zip文件在通过浏览器下载时打开文件。

我已经制作了一个Java服务来测试这个PHP脚本,人们可以用Java代码接收zip文件。

当我将收到的Java代码复制到zip文件中时,我收到一条消息,说zip文件已损坏。

有人可以建议。

谢谢。

PHP代码

 $zip = new ZipArchive();
    $filename = "labels.zip";

    $fileArray = array();
    if ($zip->open($filename, ZipArchive::CREATE)!==TRUE) {
        exit("cannot open <$filename>
");
    }

    foreach ($labelPaths as $labelPath) {
        $zip->addFile($labelPath);
    }
    $zip->close();

    header($_SERVER['SERVER_PROTOCOL'].' 200 OK');
    header("Content-Type: application/zip");
    header("Content-Transfer-Encoding: Binary");
    header("Content-Length: ".filesize($filename));
    header("Content-Disposition: attachment; filename="".basename($filename).""");
    readfile($filename);

JAVA代码:

import java.io.*;
import java.net.*;

public class checkservice {

public static void main(String[] args ) {
    excutePost();
}

public static String excutePost() {
    String targetURL = "http://localhost/intellij/trunk/website/main/productlist.php";

    String urlParameters = "<?xml version="1.0" encoding="UTF-8"?><ProcessShipmentRequest><WebAuthenticationDetail></WebAuthenticationDetail><TransactionDetail> <CustomerTransactionId>987531353</CustomerTransactionId></TransactionDetail><RequestedShipment><Hawb>1234444</Hawb><Service>INT</Service><Mawb>1234444</Mawb><Date>31/10/2017</Date><Company>AZZAM</Company><Contact>AZZAM</Contact>"
    +"<Address1>LINE1</Address1><Address2>LINE2</Address2><Address3>LINE3</Address3><Town>STONY BROOK</Town><Country>US</Country><Postcode>11790</Postcode><telephone>123333</telephone><noOfPieces>1</noOfPieces><Weight>1</Weight>"
    +"<DoxNonDox>NDX</DoxNonDox><Description>COMPUTER</Description><Value>1</Value><Weight>1</Weight><Currency>USD</Currency><Agent>DHL</Agent><Notes>JUST A TEST</Notes></RequestedShipment><RequestedShipment><Hawb>1234444</Hawb>"
    +"<Service>INT</Service><Mawb>1234444</Mawb><Date>31/10/2017</Date><Company>AZZAM</Company><Contact>AZZAM</Contact><Address1>LINE1</Address1><Address2>LINE2</Address2><Address3>LINE3</Address3><Town>STONY BROOK</Town>"
    +"<Country>US</Country><Postcode>11790</Postcode><telephone>123333</telephone><noOfPieces>1</noOfPieces><Weight>1</Weight><DoxNonDox>NDX</DoxNonDox><Description>COMPUTER</Description><Value>1</Value><Weight>1</Weight><Currency>USD</Currency>"
    +"<Agent>DHL</Agent><Notes>JUST A TEST</Notes></RequestedShipment><RequestedShipment><Hawb>1234444</Hawb><Service>TIP</Service><Mawb>1234444</Mawb><Date>31/10/2017</Date><Company>AZZAM</Company><Contact>AZZAM</Contact><Address1>LINE1</Address1><Address2>LINE2</Address2><Address3>LINE3</Address3><Town>STONY BROOK</Town>"
    +"<Country>US</Country><Postcode>11790</Postcode><telephone>123456789</telephone><noOfPieces>1</noOfPieces><Weight>1</Weight><DoxNonDox>NDX</DoxNonDox><Description>COMPUTER</Description><Value>1</Value><Weight>1</Weight><Currency>USD</Currency>"
    +"<Agent>DHL</Agent><Notes>JUST A TEST</Notes></RequestedShipment></ProcessShipmentRequest>";

    URL url;
    HttpURLConnection connection = null;
    try {
        //Create connection
        url = new URL(targetURL);
        connection = (HttpURLConnection)url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type",
                "application/x-www-form-urlencoded");

        connection.setRequestProperty("Content-Length", "" +
                Integer.toString(urlParameters.getBytes().length));
        connection.setRequestProperty("Content-Language", "en-US");

        connection.setUseCaches (false);
        connection.setDoInput(true);
        connection.setDoOutput(true);

        //Send request
        DataOutputStream wr = new DataOutputStream (
                connection.getOutputStream ());
        wr.writeBytes (urlParameters);
        wr.flush ();
        wr.close ();

        //Get Response
        InputStream is = connection.getInputStream();
        BufferedReader rd = new BufferedReader(new InputStreamReader(is));
        String line;
        StringBuffer response = new StringBuffer();
        while((line = rd.readLine()) != null) {
            response.append(line);
            response.append('
');
        }


        rd.close();
        return response.toString();

    } catch (Exception e) {

        e.printStackTrace();
        return null;

    } finally {

        if(connection != null) {
            connection.disconnect();
        }
    }
}
}
答案

这将是你的问题:

    String line;
    StringBuffer response = new StringBuffer();
    while((line = rd.readLine()) != null) {
        response.append(line);
        response.append('
');
    }

上述方法适用于从输入流中读取字符串,但您正在读取ZIP文件的二进制数据并将其视为字符串。然后将该字符串打印到控制台,然后将其复制到文本文件中 - 那里有很多失败点!

实际上,上述过程将永远不会奏效。

这几乎肯定会因为在该过程的每个步骤中的编码问题而失败,如果没有别的,另外你还要插入每个换行符的 r n字符(这也是错误的。)

相反,您只想将数据视为字节,并使用字节数组作为缓冲区(而不是字符串)将其直接泵入文件:

try(FileOutputStream out = new FileOutputStream(outFile)) {
    byte[] buffer = new byte[1024];
    int read;
    while ((read = inputStream.read(buffer)) != -1) {
        out.write(buffer, 0, read);
    }
}

以上是关于Zip文件在接收时损坏的主要内容,如果未能解决你的问题,请参考以下文章

设置文件大小时php下载限制zip损坏

上传到服务器时 Zip 文件损坏

如何在 C# 中使用 Ionic-zip 下载大文件时修复 zip 文件损坏错误

下载带有请求的 zip 文件时,文件最终被损坏

Golang 存档/zip 产生损坏的 zip 文件

下载的 zip 文件损坏