2016-08-16 40 views
0

我在2個設備之間發送文件,所以我建立了一個套接字通信。現在,我只是想發送一個文件,但將來我想發送多個文件(由用戶從gridview中選擇)。發送多個文件 - 每個文件在字節[]緩衝區中的結尾

問題是,當我發送一個文件時,在服務器端(接收文件),socket.getInputStream()。read(buffer)不檢測文件的結尾。它只是等待「更多」的數據發送。

在搜索了一下這個問題後,我找到了一些這樣的話題給了我一些選擇,但我仍然不滿意它,因爲我不知道這些選項是否有效發送多個文件。這是一個例子:How to identify end of InputStream in java

我可以在發送文件後關閉套接字或流對象,但是如果我想發送大量文件,總是關閉並打開套接字效率不高。在接收器上

代碼:

File apkReceived = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/testeReceiveServerComm.apk"); 
    byte[] buffer = new byte [8192]; 
    FileOutputStream fos=new FileOutputStream(apkReceived); 
    int count=0; 
    int total=0;//so apra ir vendo quanto recebi. 
    while((count = in.read(buffer)) != -1){ 
     fos.write(buffer,0,count); 
     total+=count; 
     System.out.println("Server Comm receive thread - already received this ammount : "+total); 

    } 

代碼在客戶端(發送方):

File apkToSend=new File(filePath); 
    byte[] buffer = new byte [8192]; 
    BufferedInputStream bis=new BufferedInputStream(new FileInputStream(apkToSend)); 
    int count; 
    int total=0; 
    while((count=bis.read(buffer))!=-1){ 
     out.write(buffer,0,count); 
     total+=count; 
     out.reset(); 
     System.out.println("send thread - already sent this ammount : "+total); 
      } 

      out.flush(); 
      bis.close(); 
+0

不要依賴流結束。它更簡單。只需發送文件的大小。您可以將大小放在一個整數變量中,然後發送整數的四個字節。接收器首先讀取四個字節並知道大小。然後它將從流中讀取確切大小的字節。完成後,再讀取四個字節作爲下一個文件的大小。當所有四個字節都爲零時,不再有文件。 – greenapps

+0

最簡單的方法是使用[協議緩衝](https://developers.google.com/protocol-buffers/)爲1)寫一個文件「描述符」(路徑,文件名,描述,文件大小等)和基於'filesize'寫出確切的字節數,然後轉到1),讀取器在其輸入流 – pskink

+0

上做同樣的事情謝謝你們倆。 Greenapps的方法類似於Riyaz Parasara所寫的答案,所以我實現了類似的東西。 Psink非常感謝你的回答,肯定會檢查協議緩衝區,也許它會更有效率(我只會讀1次以獲得大小和文件?)。再次,謝謝你的回答 –

回答

1

您正在閱讀的插座,直到讀()返回-1。這是流結束條件(EOS)。 EOS在對等關閉連接時發生。不是當它完成寫入一個文件。

您需要在每個文件前發送文件大小。你已經在做文件計數的類似事情了。然後,請務必閱讀正是許多字節爲該文件:

,這是示例代碼

String filename = dis.readUTF(); 
long fileSize = dis.readLong(); 
FileOutputStream fos = new FileOutputStream(filename); 
while (fileSize > 0 && (n = dis.read(buf, 0, (int)Math.min(buf.length, fileSize)) != -1) 
{ 
    fos.write(buf,0,n); 
    fileSize -= n; 
} 
fos.close(); 

你可以附上這一切都在一個循環終止時的readUTF()拋出EOFException類。相反,當然,在發送數據之前,您必須在發件人處調用writeUTF(filename)和writeLong(filesize)。

+0

謝謝你的回答。關於循環,我總是聽說我應該把它放在一邊(!serverSocket.isClosed())...但最近在這裏stackoverflow有人告訴我,它是壞的。難道認爲它不好?再次謝謝你 ! –

+0

沒有它不壞,技術上和理論上對我的答案是正確的 –

相關問題