2016-08-12 28 views
0

我想服務器和客戶端之間傳輸文件,服務器是用Delphi編寫與印Windows程序和客戶端是一個AndroidRecieving文件與插座的Android

這是從套接字讀取我的客戶端代碼:

... 
InputStream IS = S.getInputStream(); 
byte[] FBytes = new byte[FileSize]; 
FileOutputStream FOS = new FileOutputStream(TempFile); 
BufferedOutputStream BOS = new BufferedOutputStream(FOS); 
int BytesRead = IS.read(FBytes); 
int CurrProgress = BytesRead; 
do { 
    Log.d("DOWNLOAD", "BytesRead2 = " + Integer.toString(BytesRead)); 
    if(CurrProgress < FBytes.length) { 
     Log.d("DOWNLOAD", "prog < BytesRead"); 
     BytesRead = IS.read(FBytes); 
     if (BytesRead > 0) 
      CurrProgress += BytesRead; 
     B.clear(); 
     B.putInt("ProgValue", CurrProgress); 
     Msg.what = MSG_FILE_PROGRESS; 
     Hdlr.dispatchMessage(Msg); 
     Log.d("DOWNLOAD", "BytesRead = " + Integer.toString(BytesRead)); 
    } 
} while (BytesRead > 0); 
Log.d(TAG, "Download Loop Finished"); 

文件將下載,但問題是下載文件的大小低於原始文件和套接字讀取命令停留在上次讀取。換句話說,文件已經被下載,但CurrProgress比FBytes.length更低,因此while循環執行一次性越來越因爲從服務器

我一直在測試服務器發送與Windows程序並沒有更多的數據程序掛在讀命令沒有在服務器代碼沒有問題

我已經測試過很多方法是這樣,但沒有機會:

int BytesRead = IS.read(FBytes, 0, FBytes.length); 
int CurrProgress = BytesRead; 
do { 
    Log.d("DOWNLOAD", "BytesRead2 = " + Integer.toString(BytesRead)); 
    if(CurrProgress < FBytes.length) { 
     Log.d("DOWNLOAD", "prog < BytesRead"); 
     BytesRead = IS.read(FBytes, CurrProgress, (FBytes.length - CurrProgress)); 
    ... 
  • 文件大小值是正確的,閱讀文件的字節
  • 之前,從服務器作爲字符串值來

有什麼不順心,謝謝...

編輯:?!

完整代碼做很多其他的工作,但閱讀文件的代碼是這樣的:

public void Run() 
    { 
     Running = true; 

     try{ 
      try{ 
       InetAddress ServerAddr = InetAddress.getByName(SERVER_IP); 
       S = new Socket(ServerAddr, SERVER_PORT); 
       Log.d(TAG, "Connecting ..."); 
       Out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(S.getOutputStream())), true); 
       In = new BufferedReader(new InputStreamReader(S.getInputStream())); 
       switch (Job) { 
        ... 
        } 
        case GetFile: { 
         this.SendMessage(Cmd); 
         response = In.readLine(); 
         if(response.equals("1")) 
         { 
          Hdlr.sendEmptyMessage(MSG_SERVER_ACCEPT); 

          response = In.readLine(); 
          int FileSize = Integer.parseInt(response); 

          if (context.getFilesDir().getFreeSpace() < 3 * FileSize) 
          { 
           Hdlr.sendEmptyMessage(MSG_ERROR_FREESPACE); 

           Log.d(TAG, "There is no Free Space !"); 
          } 
          else { 

           final Message Msg = new Message(); 
           final Bundle B = new Bundle(); 
           B.putInt("FSize", FileSize); 
           Msg.what = MSG_FILE_SIZE; 
           Msg.setData(B); 
           Hdlr.dispatchMessage(Msg); 

           try { 
            File TempDir, TempFile, MainDir, MainFile; 

            switch(FileType) 
            { 
             case 2 : 
              TempDir = new File(context.getCacheDir(), "TempMP3"); 
              if(!TempDir.exists()) { 
               TempDir.mkdir(); 
              } 
              TempFile = new File(TempDir, Integer.toString(FileIndex) + ".mp3"); 
              if(TempFile.exists()) { 
               TempFile.delete(); 
              } 
              break; 
             default : 
              TempDir = new File(context.getCacheDir(), "TempLevel"); 
              if(!TempDir.exists()) { 
               TempDir.mkdir(); 
              } 
              TempFile = new File(TempDir, Integer.toString(FileIndex) + ".zip"); 
              if(TempFile.exists()) { 
               TempFile.delete(); 
              } 
            } 

            InputStream IS = S.getInputStream(); 
            byte[] FBytes = new byte[4096]; 

            FileOutputStream FOS = new FileOutputStream(TempFile); 
            BufferedOutputStream BOS = new BufferedOutputStream(FOS); 
            int BytesRead = 0; 
            int CurrProgress = 0; 

            do { 
             Log.d("DOWNLOAD", "prog < BytesRead"); 
             BytesRead = IS.read(FBytes, 0, FBytes.length); 
             BOS.write(FBytes, 0, BytesRead); 

             if (BytesRead > 0) 
              CurrProgress += BytesRead; 

             B.clear(); 
             B.putInt("ProgValue", CurrProgress); 
             Msg.what = MSG_FILE_PROGRESS; 
             Hdlr.dispatchMessage(Msg); 

             Log.d("DOWNLOAD", "BytesRead = " + Integer.toString(BytesRead)); 
            } while (CurrProgress < FileSize); 

            Log.d(TAG, "Download Loop Finished"); 
            if (CurrProgress != FBytes.length) { 
             BOS.close(); 

             Hdlr.sendEmptyMessage(MSG_ERROR_FILESIZE); 
             Log.d(TAG, "File Size Problem"); 
            } else { 
             BOS.close(); 
             Log.d(TAG, "File Downloaded successfully, Preparing to Unzip ... "); 
             try { 

              MainDir = new File(context.getFilesDir(), "Levels"); 
              if(!MainDir.exists()) 
              { 
               MainDir.mkdir(); 
              } 

              File LevelDir = new File(MainDir, Integer.toString(FileIndex)); 
              if(!LevelDir.exists()) 
              { 
               LevelDir.mkdir(); 
              } 
              else 
              { 
               LevelDir.delete(); 
              } 

              FileInputStream fin = new FileInputStream(TempFile); 
              ZipInputStream zin = new ZipInputStream(fin); 
              ZipEntry ze = null; 
              while ((ze = zin.getNextEntry()) != null) { 
               MainFile = new File(LevelDir, ze.getName()); 
               FileOutputStream FOut = new FileOutputStream(MainFile); 
               for (int c = zin.read(); c != -1; c = zin.read()) { 
                FOut.write(c); 
               } 

               zin.closeEntry(); 
               FOut.close(); 
              } 
              zin.close(); 
             } catch (Exception e) { 
              Log.d(TAG, "Unzip Error : ", e); 
             } 
            } 
           } catch (Exception E) { 
            Err = 1; 
            Log.d(TAG, "Get File Error : ", E); 
           } 
          } 
         } 
         else 
         { 
          if (Listener != null) 
          { 
           Listener.callbackMessageReceiver(response); 

           Hdlr.sendEmptyMessage(MSG_ERROR_SERVER); 
          } 
         } 

         break; 
        } 
        ... 
       } 

      }catch (Exception e) 
      { 
       Hdlr.sendEmptyMessage(MSG_ERROR_SEND); 
       Log.d(TAG, "Connect Error : ", e); 
      } 
      finally{ 
       if(Out != null) { 
        Out.flush(); 
        Out.close(); 
       } 
       if(In != null) 
       { 
        In.close(); 
       } 

       S.close(); 
       Log.d(TAG, "Err Value is : " + Integer.toString(Err)); 
       if(Err == 0) 
       { 
        Hdlr.sendEmptyMessage(MSG_SUCCESS); 
       } 

       Log.d(TAG, "Sending Ends"); 
      } 
     }catch (Exception E){ 
      Log.d(TAG, "Error : ", E); 

     } 
    } 

CurrProgress較低而不是FileSize(差別大約是4或5 KB),while循環掛在讀命令上!

+0

是的,我看到的。請告訴我們文件大小以及丟失多少字節。 – greenapps

+0

'if(CurrProgress greenapps

+0

你在循環之前已經讀過了。不太好。完成循環中的所有讀取。 – greenapps

回答

0

問題解決了,我將它張貼作爲答案,也可能是

的問題是服務器發送文件大小後立即發送文件有用,我想的BufferedReader取得文件的一些字節,因此給出的字節大小IS比文件大小更低,例如服務器:

... 
WriteLn(FileSize); 
Write(FileStream); 
... 

現在,服務器首先發送文件大小,然後等待來自客戶端的響應,它向服務器發送一個準備響應客戶端檢查自由空間後,然後服務器發送文件流,例如:

在客戶端個
... 
WriteLn(FileSize); 
Response := ReadLn(); 
if Response = "READY" then 
Write(FileStream); 
... 

和代碼是這樣的:

... 
BufferedInputStream BIS = new BufferedInputStream(S.getInputStream()); 
In = new BufferedReader(new InputStreamReader(S.getInputStream())); 
... 
response = In.readLine(); 
int FileSize = Integer.parseInt(response); 
if (context.getFilesDir().getFreeSpace() < 3 * FileSize) 
{ 
    Hdlr.sendEmptyMessage(MSG_ERROR_FREESPACE); 
    Log.d(TAG, "There is no Free Space !"); 

    this.SendMessage("NOT_READY"); 
} 
else { 
    ... 
    try { 
     this.SendMessage("READY"); 

     byte[] FBytes = new byte[8192]; 
     FileOutputStream FOS = new FileOutputStream(TempFile); 
     BufferedOutputStream BOS = new BufferedOutputStream(FOS); 
     int BytesRead = 0; 
     int CurrProgress = 0; 
     while (CurrProgress < FileSize){ 
      Log.d("DOWNLOAD", "Available : " + Integer.toString(BIS.availabl 
      BytesRead = BIS.read(FBytes, 0, FBytes.length); 
      BOS.write(FBytes, 0, BytesRead); 
      if (BytesRead > 0) 
       CurrProgress += BytesRead; 
      B.clear(); 
      B.putInt("ProgValue", CurrProgress); 
      Msg.what = MSG_FILE_PROGRESS; 
      Hdlr.dispatchMessage(Msg); 
      Log.d("DOWNLOAD", "BytesRead = " + Integer.toString(BytesRead)); 
     } 

是沒有問題的,一切工作正常