2012-03-04 12 views
6

Fileオブジェクト、オフセット、およびバイト配列パラメータをとり、そのバイト配列をJavaのFileオブジェクトに書き込む関数を記述しようとしています。Java OutputStream Skip(offset)

ので機能は

public void write(File file, long offset, byte[] data) 

のようになります。しかし、問題は、オフセットパラメータが長いタイプですので、私はオフセットとして整数を受け取りのOutputStreamの書き込み()関数を使用することができないということです。

Skip(long)を持つInputStreamとは異なり、OutputStreamはファイルの最初のバイトをスキップできません。

この問題を解決する良い方法はありますか?

ありがとうございます。

+0

「int」に入れることのできる最大数は2,147,483,647です。書きたいアレイが+ 2GBよりも大きいですか? –

+0

説明のために、オフセットは出力ストリームではなく*配列*内の位置にのみ適用されます。 OutputStreamでは、位置をスキップすることはできません。 –

+0

@TheNail offsetは、ファイルの先頭からのオフセットであり、配列の先頭ではありません。そして、FATをファイルシステムとして使用していない限り、実際には2Gbより大きなファイルを持つことができます。 – Dunes

答えて

11
try { 
    FileOutputStream out = new FileOutputStream(file); 
    try { 
     FileChannel ch = out.getChannel(); 
     ch.position(offset); 
     ch.write(ByteBuffer.wrap(data)); 
    } finally { 
     out.close(); 
    } 
} catch (IOException ex) { 
    // handle error 
} 
4

これはストリームのセマンティクスに関係します。入力ストリームでは、最初のnバイトのデータを破棄しているだけです。しかし、OutputStreamでは、何かをストリームに書き込む必要があります。あなたは、ストリームがnバイトのデータが書き込まれたが、実際に書き込まれていないことを推測するだけでは不十分です。理由は、すべてのストリームがシークできるわけではないからです。ネットワークを介して送信されるデータは検索できません。一度だけデータを取得します。ただし、ハードドライブに保存され、ハードドライブ上の任意の位置にシークするのは簡単なため、ファイルではそうではありません。

ソリューション:FileChannelsまたはRandomAccessFile insteeadを使用してください。

1

ファイルの最後に書き込む場合は、追加モード(FileOutputStream(String name、boolean append))を使用します。私の謙虚な意見では、FileOutputStreamにスキップメソッドが存在するはずですが、書き込みのためにファイル内の特定の場所に移動したい場合は、シーク可能なFileChannelまたはRandomAccessFileを使用する必要があります他人が言った)。