【问题标题】:Image/Video/Audio Succeed in Upload from Android to PHP but Can't open them - damaged/corrupted图像/视频/音频成功从 Android 上传到 PHP,但无法打开它们 - 损坏/损坏
【发布时间】:2014-10-30 19:25:27
【问题描述】:

我在我的 Android 应用程序中发出这个 HTTP POST 请求:

    private final String delimiter = "--";
    private final String boundary = "SwA"
            + Long.toString(System.currentTimeMillis()) + "SwA";
    private final String charset = "UTF-8";
    private final String lineSpace = "\r\n";
    private final String domain = (domain);

    private HttpURLConnection configureConnectionForMultipart(String url)
            throws MalformedURLException, IOException {
        HttpURLConnection con = (HttpURLConnection) (new URL(url))
                .openConnection();
        con.setRequestMethod("POST");
        con.setDoInput(true);
        con.setDoOutput(true);
        con.setRequestProperty("Connection", "Keep-Alive");
        con.setRequestProperty("Content-Type", "multipart/form-data;boundary="
                + boundary);
        return con;
    }

    private void addFormPart(String paramName, String value, DataOutputStream os)
            throws IOException {
        os.writeBytes(lineSpace + delimiter + boundary + lineSpace);
        os.writeBytes("Content-Disposition: form-data; name=\"" + paramName
                + "\"" + lineSpace);
        os.writeBytes("Content-Type: text/plain; charset=" + charset
                + lineSpace);
        os.writeBytes(lineSpace + value + lineSpace);
        os.flush();
    }

    private void addFilePart(String paramName, File data, DataOutputStream os)
            throws IOException {
        os.writeBytes(lineSpace + delimiter + boundary + lineSpace);
        os.writeBytes("Content-Disposition: form-data; name=\"" + paramName
                + "\"; filename=\"" + data.getAbsolutePath() + "\"" + lineSpace);
        os.writeBytes("Content-Type: application/octet \r\n");
        os.writeBytes("Content-Transfer-Encoding: binary" + lineSpace);
        // os.writeBytes(lineSpace);
        os.flush();

        FileInputStream fis = new FileInputStream(data);
        byte[] buffer = new byte[4096];
        int bytesRead = -1;
        while ((bytesRead = fis.read(buffer)) != -1) {
            os.write(buffer, 0, bytesRead);
        }
        os.writeBytes(lineSpace);
        os.flush();
        fis.close();
    }

    private void finishMultipart(DataOutputStream os) throws IOException {
        // os.writeBytes(lineSpace);
        os.flush();
        os.writeBytes(delimiter + boundary + delimiter + lineSpace);
        os.close();
    }

private class ObjectUploadRunnable implements Runnable {

        private final String _filePath;
        private final String _url = domain + "upload.php";

        public ObjectUploadRunnable(String filePath) {
            _filePath = filePath;
        }

        @Override
        public void run() {

            try {
                HttpURLConnection con = configureConnectionForMultipart(_url);
                con.connect();
                DataOutputStream os = new DataOutputStream(
                        con.getOutputStream());
                File data = new File(_filePath);
                addFilePart("data", data, os);
                finishMultipart(os);
                String response = getResponse(con);
                Log.i("BoxUpload", response);
                con.disconnect();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

我使用脚本 upload.php 在我的服务器上捕获它:

...
$dir = "/uploads/";
$target_path = $dir.basename($_FILES['data']['name']);

if (move_uploaded_file($_FILES['data']['tmp_name'], $target_path)) {
    echo "file uploaded";
} else {
    echo print_r(error_get_last());
}

一切似乎都成功了,一个大小正确的文件被上传到我的服务器,位于所需的目录中。但是,当我尝试打开文件时,它似乎以某种方式损坏或损坏,因为它不会在我尝试的任何应用程序中打开。我正在上传图片=jpeg,视频=mp4,音频=mp4。这些文件在上传之前都在客户端上工作。我是否缺少在 POST 请求中正确编码文件的内容?我以前从来没有上传过文件,所以我很感激一些建议......

编辑

如果这是相关的,我注意到我上传的文件增加了 ~100kb。也许某些东西被添加到我的二进制数据中,这会破坏文件?

【问题讨论】:

  • 您只是假设上传永远不会失败。馊主意。 总是在你做任何其他事情之前检查 $_FILES 中的['errors'] 参数。
  • 好的,我做了一个 var_dump[$_FILES) 并且错误字段显示 0 个错误。这足够了吗?我认为实际上传中没有任何错误,因为正确大小的文件已上传到我打算去的地方。我就是打不开。

标签: php android


【解决方案1】:

在这里解决了问题。我在 addFilePart 中注释掉的那一行实际上是必要的。我想在请求的那部分中,标题信息和二进制数据之间需要有两行。为了清楚起见,它应该如下所示:

private void addFilePart(String paramName, File data, DataOutputStream os)
        throws IOException {
    os.writeBytes(lineSpace + delimiter + boundary + lineSpace);
    os.writeBytes("Content-Disposition: form-data; name=\"" + paramName
            + "\"; filename=\"" + data.getAbsolutePath() + "\"" + lineSpace);
    os.writeBytes("Content-Type: application/octet \r\n");
    os.writeBytes("Content-Transfer-Encoding: binary" + lineSpace);
    os.writeBytes(lineSpace);
    os.flush();

    FileInputStream fis = new FileInputStream(data);
    byte[] buffer = new byte[4096];
    int bytesRead = -1;
    while ((bytesRead = fis.read(buffer)) != -1) {
        os.write(buffer, 0, bytesRead);
    }
    os.writeBytes(lineSpace);
    os.flush();
    fis.close();
}

现在一切都很好!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 2019-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多