2013-11-18 2 views
1

Я пытаюсь загрузить файл в REST API from Egnyte Если я не использую setFixedLengthStreamingMode (...), файл загружается без получения исключений, когда я использую setFixedLengthStreamingMode (...) Я получаю один раз, когда IO/SSL Exception -> Broken pipe.HTTURLConnection setFixedLengthStreamingMode приводит к исключению SSL-прерывания

Зачем мне это нужно? Поскольку документация HTTURLConnection указывает, если вы не задаете длину содержимого или используете setChunkedStreamingMode(), тогда весь файл будет кэшироваться в памяти клиента, прежде чем отправлять ему то, что не хорошо, потому что если файл слишком велик, я мог бы получить исключение OOM. Вы видите что-то, отсутствующее в моем коде?

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

    String lineEnd = "\r\n"; 
    String twoHyphens = "--"; 
    String boundary = "*****"; 

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

    try { 
     File file = new File(pathToOurFile); 
     fileInputStream = new FileInputStream(file); 

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

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

     int payloadLength = 0; 
     for (String string : payload) { 
      payloadLength += string.getBytes("UTF-8").length; 
     } 
     Logger.d(TAG, "payload length: " + payloadLength); 
     fileLength = fileInputStream.available(); 
     Logger.d(TAG, "bytes: " + fileLength); 

     // Not working: 
     //   connection.setFixedLengthStreamingMode(fileLength + payloadLength); 

     fileSize = fileLength; 

     // Allow Inputs & Outputs 
     connection.setDoInput(true); 
     connection.setDoInput(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", "Keep-Alive"); 
     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); 
     //   String mimeType = Utils.getMimeType(file.getName()); 
     //   connection.setRequestProperty("Content-Type", mimeType); 

     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]; 

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

     final int updateIntervalMilliseconds = 500; // update the UI 2 times a second 
     boolean stopUploading = (FileState.UPLOADING != mFileInfo.getState() || isCancelled()); 
     long totalBytesRead = 0; 
     long lastProgressTime = 0; 

     while (bytesRead > 0 && !stopUploading) 
     { 
      Logger.d(TAG, "bytes read: " + totalBytesRead); 
      stopUploading = (FileState.UPLOADING != mFileInfo.getState() || isCancelled()); 
      if (!stopUploading) { 
       totalBytesRead += bytesRead; 

       outputStream.write(buffer, 0, bufferSize); 
       fileLength = fileInputStream.available(); 
       bufferSize = Math.min(fileLength, maxBufferSize); 
       bytesRead = fileInputStream.read(buffer, 0, bufferSize); 

       // send a progress update event in regular intervals 
       long now = System.currentTimeMillis(); 
       if (now - lastProgressTime > updateIntervalMilliseconds) { 
        lastProgressTime = now; 
        final int percentCompleted = (int) ((totalBytesRead * 100)/fileSize); 
        if (!stopUploading && mFileInfo.getProgress() != percentCompleted) { 
         mFileInfo.sendEvent(FileEvent.UPLOAD_PROGRESS, percentCompleted); 
        } 
       } 
      } 
     } 

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

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

     if (serverResponseCode == HttpStatus.SC_OK || serverResponseCode == HttpStatus.SC_CREATED) { 
      return JBError.JBERR_SUCCESS; 
     } else { 
      return serverResponseCode; 
     } 

    } catch (SocketTimeoutException e) { 
     //applayExponentialBackoff(n); 
     Log.e(TAG, "SocketTimeoutException"); 
     return JBError.JBERR_NO_NETWORK; 
    } catch (UnknownHostException e) { 
     Log.e(TAG, "UnknownHostException"); 
     return JBError.JBERR_NO_NETWORK; 
    } catch (SocketException e) { 
     Log.e(TAG, "SocketException"); 
     return JBError.JBERR_NO_NETWORK; 
    } catch (IOException e) { 
     Log.e(TAG, "IOException"); 
     e.printStackTrace(); 
     return JBError.JBERR_FAILED; 
    } catch (Exception ex) { 
     Log.e(TAG, "Exception"); 
     ex.printStackTrace(); 
     return JBError.JBERR_FAILED; 
    } finally { 
     if (connection != null) { 
      connection.disconnect(); 
     } 
     try { 
      if (fileInputStream != null) { 
       fileInputStream.close(); 
      } 
      if (outputStream != null) { 
       outputStream.flush(); 
       outputStream.close(); 
      } 

     } catch (IOException e) { 
      Log.e(TAG, "IOException"); 
      e.printStackTrace(); 
     } 
    } 
} 

ответ

1

Длина контента рассчитана правильно? Если вы не уверены, попробуйте вместо фиксированной длины использовать режим chunked. Для android это что-то вроде setChunkedStreamingMode (int chunkLength).

Смежные вопросы