2014-06-16 44 views
1

我们怎样才能将大文件以块的形式上传到PHP服务器,这样如果连接失败,上传可以随时恢复。Android上传文件到PHP

具体来说,Android需要哪些库来做到这一点?

用户正在从互联网连接缓慢/不稳定的国家上传大文件。谢谢

编辑

更多信息,我目前使用HTTP POST上传整个文件一次。如下面的代码所示:

private int uploadFiles(File file) { 
     String zipName = file.getAbsolutePath() + ".zip"; 
     if(!zipFiles(file.listFiles(), zipName)){ 
      //return -1; 
      publishResults(-1); 
     } 
     //publishProgress(-1, 100); 
     HttpURLConnection connection = null; 
     DataOutputStream outputStream = null; 
     DataInputStream inputStream = null; 

     SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); 
     String serverUrl = prefs.getString("serverUrl", "ServerGoesHere"); // todo ensure that a valid string is always stored 
     String lineEnd = "\r\n"; 
     String twoHyphens = "--"; 
     String boundary = "*****"; 
     int bytesRead, bytesAvailable, bufferSize; 
     byte[] buffer; 
     int maxBufferSize = 1 * 1024 * 1024; 
     int responseCode = -1; 
     try { 
      //notif title, undeterministic 
      pNotif.setContentText("Zipping complete. Now Uploading...") 
        .setProgress(0, 0, true); 
      mNotifyManager.notify(NOTIFICATION_ID, pNotif.build()); // make undeterministic 

      //update progress bar to indeterminate 
      sendUpdate(0, 0, "Uploading file."); // sendupdate using intent extras 

      File uploadFile = new File(zipName); 
      long totalBytes = uploadFile.length(); 
      FileInputStream fileInputStream = new FileInputStream(uploadFile); 

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

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

      connection.setRequestMethod("POST"); 

      connection.setRequestProperty("Connection", "Keep-Alive"); 
      connection.setRequestProperty("Content-Type", 
        "multipart/form-data;boundary=" + boundary); 
      outputStream = new DataOutputStream(connection.getOutputStream()); 
      outputStream.writeBytes(twoHyphens + boundary + lineEnd); 
      outputStream 
      .writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" 
        + zipName + "\"" + lineEnd); 
      outputStream.writeBytes(lineEnd); 

      bytesAvailable = fileInputStream.available(); 
      bufferSize = Math.min(bytesAvailable, maxBufferSize); 
      buffer = new byte[bufferSize]; 
      long bytesUploaded = 0; 
      bytesRead = fileInputStream.read(buffer, 0, bufferSize); 

      while (bytesRead > 0) { 
       bytesUploaded += bytesRead; 
       outputStream.write(buffer, 0, bufferSize); 
       bytesAvailable = fileInputStream.available(); 
       bufferSize = Math.min(bytesAvailable, maxBufferSize); 
       bytesRead = fileInputStream.read(buffer, 0, bufferSize); 
       //int percentCompleted = (int) ((100 * bytesUploaded)/totalBytes); 
       //publishProgress((int)bytesUploaded/1024, (int)totalBytes/1024); 

       System.out.println("bytesRead> " + bytesRead); 
      } 

      //publishProgress(-2, 1); // switch to clean up 
      outputStream.writeBytes(lineEnd); 
      outputStream.writeBytes(twoHyphens + boundary + twoHyphens 
        + lineEnd); 
      try { 
       responseCode = connection.getResponseCode(); 
      } catch (Exception e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      fileInputStream.close(); 
      outputStream.flush(); 
      outputStream.close(); 
      // Delete the zip file 
      new File(zipName).delete(); 
     } catch (Exception ex) { 
      new File(zipName).delete(); 
      responseCode = -1; 
      ex.printStackTrace(); 
     } 
     return responseCode; 
    } 

有没有办法修改它以块发送?我所做的大部分研究并不十分清楚,对不起

+0

无法向服务器发送另一个请求,告诉它上传已完成吗?或者准备文件temp_file到几个和foreach文件调用web服务器(一个历史功能)并标记一个部分上传,你会知道10个文件中有5个被成功插入 –

+0

传输控制协议(TCP)旨在确保每个数据包以正确的顺序到达并且没有丢失。由于HTTP使用TCP,因此您可以使用HTTP PUT或POST方法上传。 – TmKVU

+0

我使用HTTP POST发送整个文件@TmKVU。 – apSTRK

回答

0

我最终使用SFTP库实现了可恢复的上传。 JSch http://www.jcraft.com/jsch/ 我使用SFTP上传,库处理可恢复模式。示例代码:

JSch jsch = new JSch(); 
session = jsch.getSession(FTPS_USER,FTPS_HOST,FTPS_PORT); 
session.setPassword(FTPS_PASS); 
java.util.Properties config = new java.util.Properties(); 
config.put("StrictHostKeyChecking", "no"); 
session.setConfig(config); 
session.connect(); 
channel = session.openChannel("sftp"); 
channel.connect(); 
channelSftp = (ChannelSftp)channel; 
channelSftp.cd(FTPS_PATH); 

File uploadFile = new File(zipName); // File to upload 
totalSize = uploadFile.length(); // size of file 

// If part of the file has been uploaded, it saves the number of bytes. Else 0 
try { 
    totalTransfer = channelSftp.lstat(uploadFile.getName()).getSize(); 
} catch (Exception e) { 
    totalTransfer = 0; 
} 

// Upload File with the resumable attribute 
channelSftp.put(new FileInputStream(uploadFile), uploadFile.getName(), new SystemOutProgressMonitor(), ChannelSftp.RESUME); 

channelSftp.exit(); 
session.disconnect(); 

有了这个库,我满足了所有需求:可恢复的上传和上传进度。

0

通过HTTP上传文件不是一个好主意,因为它是一个无状态的协议,您需要创建一个新的连接每个块想要发送到服务器。此外,您必须在手动传输之间保持状态,并且不能保证文件将以发送顺序到达。

您应该使用套接字编程和TCP套接字来维持连接,直到整个文件被发送。然后,您可以将块推入套接字,并且它们将以无损的方式到达,并以相同的顺序送入套接字。