HTTURLConnection Загрузка не работает на 100%

Я пытаюсь загрузить файл на сервер со следующим кодом, загрузка работает, но полезная нагрузка добавлена ​​в файл, вы можете увидеть его, например, загрузку текстового файла:

private Integer doFileUpload(final String urlServer) {
    HttpURLConnection connection = null;
    DataOutputStream outputStream = null;
    FileInputStream fileInputStream = null;

    final String pathToOurFile = mFileInfo.getProviderPath();
    final String lineEnd = "\r\n";
    final String twoHyphens = "--";
    final String boundary = "*****";

    int fileLength;
    int bytesToRead, bufferSize;
    final long fileSize;
    byte[] buffer;
    final int maxBufferSize = 1 * 1024 * 1024;

    try {
        final File file = new File(pathToOurFile);

        fileInputStream = new FileInputStream(file);

        final URL url = new URL(urlServer);
        connection = (HttpURLConnection) url.openConnection();

        final String[] payload = { twoHyphens + boundary + lineEnd,
                "Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + pathToOurFile + "\"" + lineEnd, lineEnd, lineEnd,
                twoHyphens + boundary + twoHyphens + lineEnd };

        int payloadLength = 0;
        for (final String string : payload) {
            payloadLength += string.getBytes("UTF-8").length;
        }
        Logger.d(AsyncEgnyteUploadFile.LOGGING_TAG, "payload length: " + payloadLength);
        fileLength = (int) file.length();
        Logger.d(AsyncEgnyteUploadFile.LOGGING_TAG, "bytes: " + fileLength);
        connection.setFixedLengthStreamingMode(fileLength + payloadLength);
        fileSize = fileLength;

        // Allow Inputs & Outputs
        connection.setDoInput(true);
        connection.setDoOutput(true);
        connection.setUseCaches(false);

        connection.setReadTimeout(5000);
        connection.setConnectTimeout(5000);

        connection.setRequestProperty("Authorization", "Bearer " + mToken);

        // Enable POST method
        connection.setRequestMethod(HttpPost.METHOD_NAME);

        connection.setRequestProperty("Connection", "close");

        // This header doesn't count to the number of bytes being sent.
        connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);

        connection.connect();
        outputStream = new DataOutputStream(connection.getOutputStream());

        outputStream.writeBytes(payload[0]);
        outputStream.writeBytes(payload[1]);
        outputStream.writeBytes(payload[2]);

        bufferSize = Math.min(fileLength, maxBufferSize);
        buffer = new byte[bufferSize];

        long totalBytesRead = 0;
        long lastProgressTime = 0;

        // Read file
        bytesToRead = fileInputStream.read(buffer, 0, bufferSize);

        boolean stopUploading = (FileState.UPLOADING != mFileInfo.getState() || isCancelled());
        while (bytesToRead > 0 && !stopUploading)
        {
            outputStream.write(buffer);
            totalBytesRead += bytesToRead;
            Logger.d(AsyncEgnyteUploadFile.LOGGING_TAG, "bytes written: " + totalBytesRead);

            final long now = System.currentTimeMillis();                

            bufferSize = (int) Math.min(fileLength - totalBytesRead, maxBufferSize);
            buffer = new byte[bufferSize];
            bytesToRead = fileInputStream.read(buffer, 0, bufferSize);
        }

        outputStream.writeBytes(payload[3]);
        outputStream.writeBytes(payload[4]);

        // Responses from the server (code and message)
        final int serverResponseCode = connection.getResponseCode();

        if (serverResponseCode == HttpStatus.SC_OK || serverResponseCode == HttpStatus.SC_CREATED) {                
            mAlreadyUploaded = true;
            return JBError.JBERR_SUCCESS;
        } else {
            Log.e(AsyncEgnyteUploadFile.LOGGING_TAG, "error code: " + serverResponseCode);
            return serverResponseCode;
        }

    } catch (final SocketTimeoutException e) {
        ..
    } catch (final UnknownHostException e) {
        ..
    } catch (final SocketException e) {
        ..
    } catch (final IOException e) {
        ..
    } catch (final Exception ex) {
        ..
    } finally {
        closeAll(connection, fileInputStream, outputStream);
    }
}

Загрузка текстового файла только с 12345 внутри с этим кодом приводит к следующему:

--*****
Content-Disposition: form-data; name="uploadedfile";filename="/storage/emulated/0/Download/3.txt"

12345
--*****--

Что я делаю неправильно?

2 ответа

Вы копируете код неправильно. Вот как копировать между потоками в Java:

while ((count = in.read(buffer)) > 0)
{
    out.write(buffer, 0, count);
}

Заметки:

  1. Вы должны проверить все чтения на конец потока.
  2. Вы должны использовать счетчик чтения в методе write().
  3. Вам не нужен новый буфер для чтения, и вам не нужен буфер размером с файл. Это будет работать с любым размером буфера больше нуля. Я обычно использую 8192.

Я подозреваю, что ваш сервер не предназначен / не настроен для обработки загрузок, состоящих из нескольких частей.

Это, конечно, выглядит так, как будто это воспринимается как простая загрузка... и я не вижу ничего, что могло бы привести к инкапсуляции из нескольких частей.

(EJP правильно, но это не то, что вызывает вашу проблему здесь. Ваш пример показывает, что все символы были отправлены...)

Другие вопросы по тегам