5

ファイルを読み取る必要があり、反復ごとにファイルから 8 バイトを読み取らなければなりません。たとえば、最初の反復では最初の 8 バイトを読み取り、2 回目の反復では次の 8 バイトなどを読み取ります。Javaでこれを行うにはどうすればよいですか?

public static byte[] toByteArray(File file) {
    long length = file.length();
    byte[] array = new byte[length];
    InputStream in = new FileInputStream(file);
    long offset = 0;
    while (offset < length) {
        int count = in.read(array, offset, (length - offset));
        offset += length;
    }
    in.close();
    return array;
}

私はこれを見つけましたが、このコードが行っていることは、ファイルを完全に読み取り、ファイル データのバイト配列を作成していると思います。しかし、1 回の反復で必要な数のバイトだけを準備する必要があります。

4

5 に答える 5

2

ニーズに合わせてコードを簡単に調整できます: オフセットとカウントを追加し、次のように呼び出しskipて初期Nバイトを通過させます -

public static byte[] toByteArray(File file, long start, long count) {
      long length = file.length();
      if (start >= length) return new byte[0];
      count = Math.min(count, length - start);
      byte[] array = new byte[count];
      InputStream in = new FileInputStream(file);
      in.skip(start);
      long offset = 0;
      while (offset < count) {
          int tmp = in.read(array, offset, (length - offset));
          offset += tmp;
      }
      in.close();
      return array;
}
于 2013-09-15T11:10:23.583 に答える
0

コードを小さなチャンクに分割します。たとえば、バイト ブロック (この場合は 8 バイト) を読み取るには、次の 3 つのことを知る必要があります。

  1. どのファイルを読み取るか
  2. どこから読み始めるか
  3. 読み取るバイト数 / ブロックのサイズ

これを 1 つのステップと見なすと、上記の 3 つのポイントをパラメーターとして取り、byte[] 配列を返すメソッドが残ります。次に例を示します。

private byte[] readByteBlock(InputStream in, int offset, int noBytes) throws IOException {
    byte[] result = new byte[noBytes];
    in.read(result, offset, noBytes);
    return result;
}

次のステップは、ファイルを開き、ファイル内のすべてのバイト ブロックに対してこのメ​​ソッドを呼び出すことです。位置 0 でファイルの読み取りを開始し、そのメソッドを 1 回呼び出し、結果に対して何かを行い、位置 = (previousPos) + blockSize ですべて呼び出します。このコードのチャンクは、別のメソッドに配置できます。たとえば、次のようになります。

public byte[][] toByteArray(File file, int byteBlockSize) throws IOException {

    InputStream in = new FileInputStream(file);
    long noOfBlocks = (long) Math.ceil((double)file.length() / (double)byteBlockSize);
    byte[][] result = new byte[(int)noOfBlocks][byteBlockSize];
    int offset = 0;
    for(int i = 0; i < result.length; i++) {
        result[i] = readByteBlock(in, offset, byteBlockSize);
    }
    return result;
}

これは、最初のインデックスを byteBlockNumber (最初の 8 バイト、2 番目の 8 バイト、3 番目の 8 バイト、...) として、2 番目のインデックスを個々のバイトごとに持つ byte[][] 配列を返します。

byte[0][0]: the first byte block's first byte
byte[0][7]: the first byte block's second byte
byte[1][2]: the second byte block, third byte
etc..

上記のコード例では、byte[][] 配列は次のように初期化されます。

long noOfBlocks = (long) Math.ceil((double)file.length() / (double)byteBlockSize);
byte[][] result = new byte[noOfBlocks][byteBlockSize];

したがって、ブロック数は、ファイル内の全体のバイト数をバイト ブロックのサイズ (この例では 8) で割ったものです。ファイルに 9 バイトがあり、ブロック サイズが 8 であると仮定すると、結果は 1,sth になり、1 に丸められるため、最後のバイトのスペースがなくなるため、Math.ceil() を使用して切り上げます。分割は与えます。Math.ceil(9 / 8) -> 2、およびこれらの 2 は、8 バイトの最初のブロックと 2 番目のブロックの最後のバイトを保持するのに十分です。

于 2013-09-15T11:42:57.270 に答える