2017-11-28 14 views
1

私の目標は、NetworkStreamを使用してTCP接続を介してファイルを送信することです。 私は最初に送信するデータの長さを送信し、その後、ファイルストリームとバイナリ・ライターを使用してバイトごとにデータを送信します。NetworkStream経由で送信されたファイルが破損しているC#

プロセスのデバッグ中に、受信側でファイルの先頭に「0」バイトが挿入されていることがわかりました。 たとえば、ベースファイルのコンテンツazertyuiopは、azerty(4スペースはuiopを置き換えます)として受信され、画像などのファイルが破損しています。

私がこれまで持っているコード: (BRはBinaryReaderで、BWはBinaryWriterある場合は)

送信者:

using (var readStream = new FileStream(fileLocation, FileMode.Open)) 
{ 
    // Send the data length first 
    bw.Write(new FileInfo(fileLocation).Length); 
    bw.Flush(); 

    var buffer = new byte[1]; 
    while (readStream.Read(buffer, 0, 1) > 0) 
    { 
      bw.Write(buffer[0]); 
      bw.Flush(); 
    } 
} 

受信機:

// Get data length 
var dataLength = br.ReadInt32(); 

using (var fs = new FileStream(newFileLocation, FileMode.Create)) 
{ 
    var buffer = new byte[1]; 
    for(int i = 0; i < dataLength; i++) 
    { 
     br.Read(buffer, 0, 1); 
     fs.Write(buffer, 0, 1); 
    } 
} 

何午前私は行方不明か間違っている?

bw.Write(new FileInfo(fileLocation).Length); 
... 
var dataLength = br.ReadInt32(); 

Length性が実際にタイプlong(8バイト)である:

+0

データの長さの送受信方法については、https://stackoverflow.com/questions/7099875/sending-messages-and-files-over-networkstreamをご覧ください。 –

+1

問題の一部ではありませんが、一度に1バイトの読み書きは非常に非効率的です。どのくらい書く必要があるかを確認するには、大きなバッファとRead呼び出しの結果を使用します。 –

+0

特にすべてのバイトをフラッシュしていません。 – pm100

答えて

2

問題は、以下のかもしれない長さです。しかし、あなたはInt32(4バイト)という値を読み込み、残りの4バイトはストリームに残しています。

+0

ありがとうございました。もう1つ質問があります。サイズ1のバイト配列を使用するよりも良い方法はありますか?多分もっと大きなサイズですか? – Valsov

+0

はい、バッファサイズを数キロバイトに増やし、それに応じてループを調整する必要があります。ストリームを読み込むときは、実際に読み込んだバイト数を返すので、Read()メソッドの戻り値に注意してください。これは、バッファが最後に読み込まれた部分よりも大きい場合でも、ストリームの終わりに達した時点を判断するのに役立ちます。そうすれば、データの長さの値を完全に使わなくても、代わりにストリームの終わりを確認するだけで済みます。 – uncoder

1

fileinfo.lengthはINT32

関連する問題