2016-08-16 10 views
0

私は2つのデバイス間でファイルを送信しているので、ソケット通信を確立しました。今は1つのファイルを送信しようとしていますが、将来は複数のファイル(グリッドビューからユーザーが選択)を送信したいと考えています。複数のファイルを送信する - 各ファイルの最後のバイト[]バッファー

問題は、私は(つまり、ファイルを受信)サーバ側で、一つのファイルを送信するときにsocket.getInputStream()。ファイルの終わりが検出されない(バッファ)をお読みください。それは単に "より多くの"データが送信されるのを待つだけです。

この問題にビットを検索した後、私は一種の私にいくつかのオプションを与えたいくつかのトピックに達したが、私はこれらのオプションは、複数のファイルを送信するために効率的である場合には知らないので、私はまだそれに満足していないです。これは一例です: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

ストリームの終わりに頼らないでください。そのはるかに簡単です。最初にファイルのサイズを送信してください。整数変数にサイズを入れ、整数の4バイトを送信することができます。受信機は、まず4バイトを読み取り、そのサイズを知る。次に、正確にsizeバイトをストリームから読み込みます。完了すると、次のファイルのサイズのために4バイトを再度読み込みます。 4バイトすべてがゼロであるとき、それ以上のファイルはありません。 – greenapps

+0

最も簡単なのは、[プロトコルバッファ](https://developers.google.com/protocol-buffers/)を使って1)ファイル "記述子"(パス、ファイル名、説明、ファイルサイズなど)を書き、 'filesize'は正確なバイト数を書いてから1になります)、読者は入力ストリームで同じことをします – pskink

+0

両方にありがとう。 Greenappsのアプローチは、Riyaz Parasaraが書いた答えと似ています。だから私は似たようなものを実装しました。 Psinkはあなたの答えをたくさんありがとう、間違いなくプロトコルのバッファをチェックします、多分もっと効率的でしょう(私はサイズとファイルを持つために1回だけ読むでしょうか?)。もう一度、あなたの答えは両方ともありがとう –

答えて

1

あなたが読むまで、ソケットを(読んでいる)が-1を返します。これはストリーム終了条件(EOS)です。ピアが接続を閉じると、EOSが発生します。 1つのファイルの書き込みが終了したときではありません。

各ファイルより先にファイルサイズを送信する必要があります。あなたは既にファイル数と同様のことをしています。あなたがのreadUTF()は、EOFExceptionではをスローしたときに終了ループでこのすべてを囲むことができ

、これはサンプルコード

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(); 

です:そして、あなたがそのファイルに正確に多くのバイトを読んで確認してください。逆に、データを送信する前に、送信側でwriteUTF(ファイル名)とwriteLong(ファイルサイズ)を呼び出す必要があります。

+0

あなたの答えをありがとう。ループについては、私はいつも(!serverSocket.isClosed())中に入れなければならないと聞きました...しかし、最近ここでstackoverflowの誰かがそれは悪いと私に言った。それは悪いと思いますか?再びありがとう ! –

+0

いいえ悪くない、技術的にも理論的にも私の答えは正しい –

関連する問題