2012-10-04 25 views
0

我有一個java文件服務器發送文件到android客戶端。出於某種原因,服務器似乎在關閉套接字後,只有一次通過,我希望它發送所有文件,然後關閉套接字,這是我的服務器代碼。在此先感謝線程java服務器只發送一個文件

public void run() { 
    DataOutputStream dos = null; 
    try { 
     String path = "/home/test"; 
     int count = 0; 
     dos = new DataOutputStream(
       new BufferedOutputStream(socket.getOutputStream())); 
     DataInputStream dis = new DataInputStream(new BufferedInputStream(
       socket.getInputStream())); 

     File[] files = new File(path).listFiles(); 
     for (File file : files) { 
      String filename = file.getName(); 
      String extension = filename.substring(
        filename.lastIndexOf(".") + 1, filename.length()); 
      if ("png".equals(extension)) { 
       count += 1; 
      } 

     } 
     System.out.println("Sending " + count + " files"); 
     dos.writeInt(count); 
     dos.flush(); 
     byte[] temp = new byte[1024]; 
     int n = 0; 
     for (File file : files) { 
      String filename = file.getName(); 
      String extension = filename.substring(
        filename.lastIndexOf(".") + 1, filename.length()); 
      if ("png".equals(extension)) { 
       FileInputStream fis = new FileInputStream(file); 
       BufferedInputStream bis = new BufferedInputStream(fis); 
       byte fileContent[] = new byte[(int) file.length()]; 
       bis.read(fileContent); 
       int dataLength = fileContent.length; 
       dos.writeInt(dataLength); 
       dos.flush(); 
       int open = dis.readInt(); 
       System.out.println("still open if open = 5: open = "+open); 
       System.out.println(filename + " is " + dataLength 
         + " bytes long"); 
       while ((dataLength > 0) 
         && (n = bis.read(temp, 0, 
           (int) Math.min(temp.length, dataLength))) != -1) { 
        dos.write(temp, 0, n); 
        dos.flush(); 
        dataLength -= n; 

       } 
       System.out.println("Sent file "+filename); 
       fis.close(); 
       bis.close(); 

      } 
     } 

    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    finally 
    { 

     try{ 
     if (dos != null) {dos.close();} 
     } catch (Exception e) { 

      e.printStackTrace(); 
     } 
    } 
} 

}

+1

一個選項可能是代碼在循環內部拋出異常。檢查你的日誌。 –

+0

有什麼異常?如果我們認爲代碼是您的測試代碼,您怎麼能確定它是客戶端問題。 –

回答

2

任何機會,你的Android應用程序在打轉?你的代碼中有一個邏輯錯誤。它將整個文件讀入到fileContent中,但是隨後進入while循環等待文件被完全讀取。

bis.read(fileContent); 
... 
while ((dataLength > 0) 
    && (n = bis.read(temp, 0, (int) Math.min(temp.length, dataLength))) != -1) { 

你在整個文件從bis所以,當你在讀更多你所得到n == 0所以它永遠循環已經被讀取。

如果你想要做緩衝,那麼你應該刪除bis.read(fileContent);。如果你想在開始時讀取文件,那麼你需要刪除while循環。

int dataLength = (int) file.length(); 
byte fileContent[] = new byte[dataLength]; 
bis.read(fileContent); 
dos.writeInt(dataLength); 
dos.write(fileContent); 
dos.flush(); 
dataLength -= n; 
+0

哦,我看到了,它現在似乎也在工作......非常感謝 – user1661396

+1

@ user1661396 - 循環版本更好。一行讀取調用不會總是讀取整個文件並可能導致內存問題。使用固定的緩衝區大小和讀取循環。 – jtahlborn