@alexvdem

Почему загрузка через HttpsURLConnection не загружает файл целиком?

Есть такой код в Android Studio:
Клиент:
spoiler
public int uploadFile(String sourceFileUri) {

    String fileName = sourceFileUri;
    HttpURLConnection conn;
    DataOutputStream dos;
    String lineEnd = "\r\n";
    String twoHyphens = "--";
    String boundary = "*****";
    int bytesRead, bytesAvailable, bufferSize;
    byte[] buffer;
    int maxBufferSize = 1*1024*1024;
    File sourceFile = new File(sourceFileUri);

    if (!sourceFile.isFile()) {

        dialog.dismiss();
        Log.e("uploadFile", "Source File not exist :"
                +uploadFilePath + "" + uploadFileName);

        runOnUiThread(new Runnable() {
            public void run() {
                messageText.setText("Source File not exist :"
                        +uploadFilePath + "" + uploadFileName);
            }
        });

        return 0;
    }
    else
    {
        try {
            // open a URL connection to the Servlet
            FileInputStream fileInputStream = new FileInputStream(sourceFile);
            URL url = new URL(upLoadServerUri);
            // Open a HTTP  connection to  the URL
            conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true); // Allow Inputs
            conn.setDoOutput(true); // Allow Outputs
            conn.setUseCaches(false); // Don't use a Cached Copy
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("ENCTYPE", "multipart/form-data");
            conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
            conn.setRequestProperty("uploaded_file", fileName);

            dos = new DataOutputStream(conn.getOutputStream());
            dos.writeBytes(twoHyphens + boundary + lineEnd);
            dos.writeBytes("Content-Disposition: form-data; name=uploaded_file;filename=" + fileName + " + lineEnd");
            dos.writeBytes(lineEnd);
            // create a buffer of  maximum size
            bytesAvailable = fileInputStream.available();
            bufferSize = Math.min(bytesAvailable, maxBufferSize);
            buffer = new byte[bufferSize];
            // read file and write it into form...
            bytesRead = fileInputStream.read(buffer, 0, bufferSize);

            while (bytesRead > 0) {
                dos.write(buffer, 0, bufferSize);
                bytesAvailable = fileInputStream.available();
                bufferSize = Math.min(bytesAvailable, maxBufferSize);
                bytesRead = fileInputStream.read(buffer, 0, bufferSize);
            }
            // send multipart form data necessary after file data...
            dos.writeBytes(lineEnd);
            dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

            // Responses from the server (code and message)
            serverResponseCode = conn.getResponseCode();
            String serverResponseMessage = conn.getResponseMessage();

            Log.i("uploadFile", "HTTP Response is : "
                    + serverResponseMessage + ": " + serverResponseCode);

            if(serverResponseCode == 200){

                runOnUiThread(new Runnable() {
                    public void run() {

                        String msg = "File Upload Completed.\n\n "
                                +uploadFileName;

                        messageText.setText(msg);
                        Toast.makeText(UploadToServer.this, "File Upload Complete.",
                                Toast.LENGTH_SHORT).show();
                    }
                });
            }

            //close the streams //
            fileInputStream.close();
            dos.flush();
            dos.close();

        } catch (MalformedURLException ex) {

            dialog.dismiss();
            ex.printStackTrace();

            runOnUiThread(new Runnable() {
                public void run() {
                    messageText.setText("MalformedURLException Exception : check script url.");
                    Toast.makeText(UploadToServer.this, "MalformedURLException",
                            Toast.LENGTH_SHORT).show();
                }
            });

            Log.e("Upload file to server", "error: " + ex.getMessage(), ex);
        } catch (Exception e) {

            dialog.dismiss();
            e.printStackTrace();

            runOnUiThread(new Runnable() {
                public void run() {
                    messageText.setText("Got Exception : see logcat ");
                    Toast.makeText(UploadToServer.this, "Got Exception : see logcat ",
                            Toast.LENGTH_SHORT).show();
                }
            });
            Log.e("Upload file Exception", "Exception : "
                    + e.getMessage(), e);
        }
        dialog.dismiss();
        return serverResponseCode;

    } // End else block
}


Сервер:
spoiler
$file_path = "uploads/files/";

$file_path = $file_path . basename( $_FILES['uploaded_file']['name']);
if(move_uploaded_file($_FILES['uploaded_file']['tmp_name'], $file_path))
{
echo "success";
}else{
echo "fail";
}


1. Маленькие файлы до 1 кб где то не загружаются от слова вообще. На сервер они не приходят, даже в папке /tmp не появляются. Большие файлы (10кб) созданный из одинаковых символов '1' к примеру не загружаются тоже. Я специально проверял.
2. Большие файлы получаются обрезанными, куда-то пропадает 1-2 килобайта данных из начала файла.
Проверял цикл
while (bytesRead > 0) {
                dos.write(buffer, 0, bufferSize);
                bytesAvailable = fileInputStream.available();
                bufferSize = Math.min(bytesAvailable, maxBufferSize);
                bytesRead = fileInputStream.read(buffer, 0, bufferSize);
            }

Он работает норм. Проходит чтение всего файла.
Думал напортачил что-то в заголовках HTTPS, но тут моих знаний не так много, но все вроде по мануалу для передачи файлов на сервер 'multipart/form-data';
Я уже день ковыряю этот код, и понять не могу, что не так. Пока понял, что на сервер во временную папку приходит именно тот код, который потом идет в 'uploads/files/'. Цикл читает весь файл. Т.е. по идее все байты направляются на сервер напрямую. Между и сервером кроме HttpsURLConnection никакой больше обработки информации нет.
Вопрос - куда пропадают байты?

PHP Version 7.4.20
Apache 2.0 Handler
  • Вопрос задан
  • 65 просмотров
Пригласить эксперта
Ответы на вопрос 1
zagayevskiy
@zagayevskiy Куратор тега Java
Android developer at Yandex
Возьми OkHttp и через него отправь этот файл, чем велосипедить эту хрень.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
ПрофСофт Саратов
от 180 000 до 250 000 ₽
Artezio Нижний Новгород
от 100 000 ₽
Artezio Санкт-Петербург
от 120 000 ₽