2011-09-10 100 views
0

即時通訊嘗試通過套接字在Android中發送文件。我想添加字節流的文件名,然後將其發送到服務器。我怎麼做?然後我如何在接收端分離文件名? 這是送文件的代碼:android add filename to bytestream

Log.i("SocketOP", "sendFILE-1"); 
      File f = new File(path); 
      String filename=path.substring(path.lastIndexOf("/")+1); 
      System.out.println("filename:"+filename); 
      fin.filename = "~"+filename; 
      BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream()); 

      FileInputStream fileIn = new FileInputStream(f); 
      Log.i("SocketOP", "sendFILE-2"); 
      byte [] buffer = new byte [(int)f.length()]; 
      System.out.println("SO sendFile f.length();" + f.length()); 
      int bytesRead =0; 
      while ((bytesRead = fileIn.read(buffer)) > 0) { 
       out.write(buffer, 0, buffer.length); 
       System.out.println("SO sendFile" + bytesRead +filename); 
      } 
      out.flush(); 
      out.close(); 
      fileIn.close(); 
      Log.i("SocketOP", "sendFILE-3"); 

回答

1

如果這是您自己的協議,那麼你創建的兩個部分(文件名和數據)分開的數據包。您需要清楚地表明通過特定邊界的分離。

在服務器上,由於您瞭解協議,服務器將讀回整個數據包,並根據給定的邊界將文件名和數據分開。

MIME data format恰好使用這種數據交換方式,並廣泛使用HTTP協議。如果您使用相同的MIME數據格式,另一個好處是,你可以使用第三方庫進行編碼和解碼的數據,如HttpMime

下面是粗糙的代碼中使用MIME數據對數據進行格式化,並通過Socket

發送
File f = new File(path); 
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream()); 
String filename=path.substring(path.lastIndexOf("/")+1); 

// create a multipart message 
MultipartEntity multipartContent = new MultipartEntity(); 

// send the file inputstream as data 
InputStreamBody isb = new InputStreamBody(new FileInputStream(f), "image/jpeg", filename); 

// add key value pair. The key "imageFile" is arbitrary 
multipartContent.addPart("imageFile", isb); 

multipartContent.writeTo(out); 
out.flush(); 
out.close(); 

請注意,您需要HttpMime項目中的org.apache.http.entity.mime.MultipartEntityorg.apache.http.entity.mime.content.InputStreamBody。在服務器上,您需要MIME解析器來獲取文件名和所有字節內容

要在服務器上讀取輸入流,您需要一個類來解析MIME消息。除非您想了解MIME消息結構,否則您不必自己編寫解析器,因爲MIME已成爲常用的消息格式。

以下是使用作爲JavaMail一部分的MimeBodyPart的示例代碼。


MimeMultipart multiPartMessage = new MimeMultipart(new DataSource() { 
    @Override 
    public String getContentType() { 
     // this could be anything need be, this is just my test case and illustration 
     return "image/jpeg"; 
    } 

    @Override 
    public InputStream getInputStream() throws IOException { 
     // socket is the socket that you get from Socket.accept() 
     BufferedInputStream inputStream = new BufferedInputStream(socket.getInputStream()); 
     return inputStream; 
    } 

    @Override 
    public String getName() { 
     return "socketDataSource"; 
    } 

    @Override 
    public OutputStream getOutputStream() throws IOException { 
     return socket.getOutputStream(); 
    } 
}); 

// get the first body of the multipart message 
BodyPart bodyPart = multiPartMessage.getBodyPart(0); 

// get the filename back from the message 
String filename = bodyPart.getFileName(); 

// get the inputstream back 
InputStream bodyInputStream = bodyPart.getInputStream(); 

// do what you need to do here.... 

你可以從Oracle Website其中也有對Java Activation Framework

+0

使用普通的TCP/IP是發送文件正確,所以我不知道有任何protocol..the代碼依賴下載的JavaMail告訴所有什麼IM做..在接收端,它簡單地獲取輸入流並將其傳遞給receiveFile方法。請告訴我如何使用httpmime lib,如果解決方案是這樣的話。謝謝。 –

+0

@hardy我會嘗試寫一個簡單的僞代碼來說明Android方面的想法。服務器寫的是什麼語言,因爲我可能沒有足夠的熟悉它來提供僞代碼。即使我不這樣做,我也可以幫助您找到解析服務器MIME消息的庫。 – momo

+0

謝謝。它的客戶端服務器的東西。所以服務器應該是一個問題。 –