3

私はC#を初めて使用するので、ご容赦ください。(FileStreamを使用して)データ(固定サイズ)を小さな配列に読み取り、データを処理してから、ファイルの最後まで再度読み取ります。

私はこのようなものを使うことを考えました:

            byte[] data = new byte[30];
            int numBytesToRead = (int)fStream.Length;
            int offset = 0;

            //reading
            while (numBytesToRead > 0)
            {
                fStream.Read(data, offset, 30);
                offset += 30;
                numBytesToRead -= 30;

                //do something with the data
            }

しかし、私はドキュメントとその例を確認し、上記のreadメソッドの戻り値は次のとおりであると述べました。

「タイプ:System.Int32バッファに読み込まれた合計バイト数。これは、そのバイト数が現在使用できない場合は要求されたバイト数より少ない場合があり、ストリームの終わりに達した場合はゼロになる可能性があります。」

それらが現在利用できないということはどういう意味ですか、これは少量のデータを読み取るときに実際に発生する可能性がありますか、それとも大量のデータに対してのみですか?他の場所でも大きなチャンクで読んでいるので、大きい場合は、おおよその大きさです。これがいつでも発生する可能性がある場合、コードが効率的に実行されるようにコードを変更するにはどうすればよいですか?

お手数をおかけしますが、よろしくお願いいたします。

4

4 に答える 4

5

read メソッドは、返されたバイト数を返します。これは、要求されたバイト数よりも少ない場合があります。通常、ファイルを読み取ると、要求したすべてのバイトが取得されます (ファイルの最後に到達しない限り)。ただし、常にそのようになるとは限りません。

システムがすぐに利用できるデータと取得に時間がかかるデータを区別する可能性があるため、現在利用可能なデータをすぐに返し、バックグラウンドでより多くのデータの読み取りを開始し、残りのデータを要求することを期待します。別の呼び出しでのデータの。私の知る限り、現在これは行われていませんが、将来の合理的なシナリオです。

メソッドの結果を取得し、Readそれを使用して、取得したデータの量を判断する必要があります。の場所にあるバッファに読み込まoffsetないでください。バッファよりも大きいファイルを読み取ることはできません。または、ストリーム全体を保持する配列を宣言してから、データを の場所に読み込むことができますoffset

また、メソッドが 0 を返す状況にも対処する必要がありReadます。これは、読み取るデータがこれ以上ないことを意味します。これは通常、ファイルの最後に到達するまで発生しませんが、終了するとコードが永遠のループに陥ります。

byte[] data = new byte[30];
int numBytesToRead = (int)fStream.Length;
int offset = 0;

//reading
while (numBytesToRead > 0) {
  int len = fStream.Read(data, 0, data.Length);
  offset += len;
  numBytesToRead -= len;
  if (len == 0 && numBytesToRead > 0) {
    // error: unexpected end of file
  }
  //do something with the data (len bytes)
}
于 2011-02-22T09:22:23.233 に答える
3

ファイルで利用できる以上の読み取りを試みてください。これは、次の 2 つのシナリオで実行できます。

  • ファイルの全長よりも多くのバイトを読み込もうとしています
  • ファイルの終わりに近すぎて、要求したバイト数を読み取ることができません

さらに、Stream には、ネットワークにバインドされた接続の子孫もあります。これらの場合、いつ、どのくらいのバイト数が使用可能になるかを知ることは必ずしも容易ではありません。

バイナリ ファイルをチャンクで処理する方法は次のとおりです。

byte[] buffer = new byte[BUFFER_SIZE];
int inBuffer;
while ((inBuffer = stream.Read(buffer, 0, buffer.Length)) > 0)
{
    // here you have "inBytes" number of bytes in the buffer
}
于 2011-02-22T08:56:13.517 に答える
1

現在利用できないバイトは、HttpWebRequestにあるような非FileStreamストリームにのみ適用されます。

理論上、FileStream.Readは1バイトを返す可能性があります。それでも、これほど小さいパケットを処理できるはずです。

ただし、SMB接続が失われた、ファイルが削除された、アンチウイルスなどの問題が発生した場合、またはファイルの最後に到達した場合を除いて、0が返されることはありません。

ファイルを読み取るためのより良い方法があります。テキストファイルを扱っている場合は、代わりにSystem.IO.StreamReaderを使用することを検討してください。これは、さまざまなテキストエンコーディング、改行などを処理するためです。

また、バッファの最大サイズは2 GBであるため、実行しないでください。new buffer[fileStream.Length]

于 2011-02-22T09:05:03.997 に答える
1

FileStreamから派生しStreamStream非常に一般的なクラスであり、Read の記述はその一般的なクラスからのものです。たとえば、ストリームはネットワーク ストリームの場合もあり、データは送信されていないため、現在利用できない場合があります。a については、FileStream次の 3 種類の戻り値が返されると想定できます。

  1. 戻り値 == 読み取るバイト数 (Read の最後のパラメーター): ファイルの途中です
  2. 戻り値 < カウント && 戻り値 > 0: ファイルの最後にいるか、ストリームの残りの部分が現在利用できない可能性があります。
  3. 戻り値 == 0: すでにすべてのコンテンツを読みました。これ以上読むものはありません。
于 2011-02-22T08:57:25.920 に答える