1

ファイルの一部をバイト配列に読み込むメソッドをコーディングしたいと考えています。このために、私は fileinputstream とバッファリングされた入力ストリームを使用しています。

このような:

fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
dis = new DataInputStream(bis);

メソッド名「OpenFile(String File)」を呼び出して、これを 1 回だけ行います。このメソッドでファイルが開かれたら、「ReadParts(byte[] buffer, int offset, int len)」という関数で操作を試みます。

dis.read(buffer, offset, len);            
for(int i = 0; i < buffer.length; i++) System.out.print((char)buffer[i]);

// used data:
// file = "C:\Temp\test.txt" with a size of 949
// buffer: always in this case with a size of 237, except for the last one its 238
// offsets: 0, 237, 474, 711 
// len is always 237, except for the last one its 238

行 dis.read() は、最初のステップの後に常に indexOutOfBounds エラーメッセージをスローしますが、その理由と内容がわかりません。インデックスの問題が見つからないため、netbeansデバッガーを使用しても役に立ちませんでした.....

4

4 に答える 4

2

Stream をバッファの配列に読み込む場合、offset と len は常に次のようにする必要があります。

offset = 0;
len = buffer.length();

これらのパラメーターは、ストリームからデータを読み取るのではなく、データをバッファー内のどこに配置するかを指定します。ストリームは連続して読み取られます (または、これはつづられますか?)!

常に呼び出す場合:

buffer = new byte[256];
dis.read(buffer, 0, 256);

これが起こります: 最初の呼び出しの前に、Streamposition (返される次のバイトの位置) は 0 です。

  1. 呼び出し後のストリーム位置 = 256 およびバッファにはバイト 0 ~ 255 が含まれます
  2. call=512 および buffer の後の Streamposition にはバイト 256-511 が含まれます
  3. ...

    dis.reset();

Streamposition は再び 0 です。

このコードは、Stream から 256 ~ 511 バイトのみをバッファーに読み取ります。

byte[] buffer = new byte[512];
dis.skip(256);
dis.read(buffer, 0, 256);

バッファの最後の 256 バイトがいっぱいになっていないことを確認します。これは、read(byte[], int, int) と read(byte[]) の違いの 1 つです。

ストリームの概念と read-method の使用法を説明するリンクを次に示します。 read() ストリーム

于 2012-03-14T11:55:01.720 に答える
1

オフセットとレンをどのように考えていますか。私の推測では、offset + len はバッファより大きいと思います。

于 2012-03-14T11:27:30.177 に答える
1

IndexOutOfBoundsException が発生します - If

  • オフセットは負、

  • len は負で、

  • len が buffer.length より大きい - オフ

ポイント 3 の例:

入力ファイルが 500 文字または 1500 文字の場合、次のプログラムは正常に実行されます。

byte[] buffer = new byte[1000];
int offset = 0;
int len = 1000;
dis.read(buffer, offset, len);            
for(int i = 0; i < buffer.length; i++) System.out.print((char)buffer[i]);

ただし、次の場合は失敗し、例外がスローされます。

byte[] buffer = new byte[1000];
int offset = 0;
int len = 1001;
dis.read(buffer, offset, len); 
for(int i = 0; i < buffer.length; i++) System.out.print((char)buffer[i]);

どちらの場合も長さの値を確認してください。

于 2012-03-14T11:47:03.253 に答える
0

オフセットは、ファイルではなくバッファ内のオフセットです。

私はあなたが何を望んでいると思います

byte[] buffer = new byte[237];

int len = dis.read(buffer); // read another 237 bytes.

if (len < 0) throw new EOFException(); // no more data.
for(int i = 0; i < len; i++)
   System.out.print((char)buffer[i]);
// or
System.out.print(new String(buffer, 0, 0, len));

デバッガーで、オフセット >= 0 およびオフセット + 長さ <= buffer.length を確認できますか?

InputStream.read() から

public int read(byte b[], int off, int len) throws IOException {
if (b == null) {
    throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
    throw new IndexOutOfBoundsException();

チェックされた条件の 1 つが無効です。

于 2012-03-14T11:27:44.597 に答える