2017-02-22 48 views
1

Javaストリームには新しいので、特定のファイルコンテンツを読み込み、最初から読み込む必要があります。私はBufferedInputStreamを作成していると私はBufferedInputStream.mark(int型markLimit)のマニュアルについて困惑しているbufferedinputstreamでのマーク読み取り制限の使用方法

ドキュメントは言う:

public void mark(int readlimit) 

このメソッドは、ストリームのことが可能に入力位置をマークreset()メソッドを呼び出すことによって「リセット」されます。パラメータreadlimitは、マークが無効になる前にマークを設定した後にストリームから読み取れるバイト数です。たとえば、mark()が読み取り制限10で呼び出された場合、reset()メソッドが呼び出される前にストリームから11バイトのデータが読み込まれると、マークは無効であり、ストリームオブジェクトインスタンスは必須ではありませんマークを覚えています。この方法によって記憶することができるバイトの数は、内部リード・バッファのサイズよりも大きくすることができる

注意。また、マーク/リセット機能をサポートする従属ストリームにも依存しません。

オーバーライド:クラスFilterInputStream内 マーク

パラメータ: readlimit - マークが無効になる前に読み込み可能なバイト数**

私のコードは次のとおりです。

public class Test { 
    public static void main(String[] args) throws IOException { 

     File resource = new File("beforeFix.txt");   
     FileInputStream fileInputStream = new FileInputStream(resource); 
     BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream); 
     int i = bufferedInputStream.read(); 
     bufferedInputStream.mark(1); 
     i = bufferedInputStream.read(); 
     i = bufferedInputStream.read(); 
     i = bufferedInputStream.read(); 
     i = bufferedInputStream.read(); 
     i = bufferedInputStream.read(); 
     i = bufferedInputStream.read(); 
     i = bufferedInputStream.read(); 
     i = bufferedInputStream.read(); 
     i = bufferedInputStream.read(); 
     i = bufferedInputStream.read(); 
     i = bufferedInputStream.read(); 
     i = bufferedInputStream.read(); 
     i = bufferedInputStream.read(); 
     i = bufferedInputStream.read(); 
     i = bufferedInputStream.read(); 
     i = bufferedInputStream.read(); 
     i = bufferedInputStream.read(); 
     i = bufferedInputStream.read(); 
     i = bufferedInputStream.read(); 
     i = bufferedInputStream.read(); 
     bufferedInputStream.reset(); 
     i = bufferedInputStream.read(); 
     i = bufferedInputStream.read(); 
     i = bufferedInputStream.read(); 
     i = bufferedInputStream.read(); 
     bufferedInputStream.reset(); 
    } 
} 

上記のコードでは、marklimitを1に設定しましたが、マークは無効ではありません。

小さな例でこれを設定する実際の目的は何ですか?仕事とバックあなたがマークの位置、あなたはメモリにバッファリングするニーズをマークした後、読み込まれたデータへ行くにリセットするためには、事前

+0

私はリセット()を呼んでいる、それは私にすべての例外をスローしません。ドキュメントごとに、マーク制限を1に設定してから2番目のバイトを読み取った後は、マークを無効にする必要がありますが、そうではありません。では、このマーク()の目的は何ですか? –

+0

引用符で囲まれたテキストに引用符形式を使用します。そして太字を外してください。それは私たちの目を傷つける。 – EJP

答えて

1

感謝。マーキング時に指定する値は、このために予約する必要があるメモリ量です。

だから、あなたがリセットを呼び出す前に100のバイトを読んでするつもりなら、あなたのバッファが少なくとも100バイトであることが必要であり、そのためには、あなたがマークを呼び出すために持っているものです。

bufferedInputStream.mark(200); 

... read no more than 200 bytes ... 

bufferedInputStream.reset(); // reset back to marked position 

更新

markのドキュメントは、実際の動作に一致していないように見えます。ドキュメントの状態:

the maximum limit of bytes that can be read before the mark position becomes invalid 

をしかし、それはthe minimum limitでなければならないように見える、または非常に少なくとも、基礎となる実装は、彼らはまだリセットサポートできる場合、読み取り制限を超えているとすぐにマークを破棄する必要はありませんマークされた位置に移動する。

+0

上記の例では、マーク制限を1に設定し、複数のバイトを読み取っています。ドキュメントごとに、マーク制限を1に設定してから2番目のバイトを読み取った後は、マークを無効にする必要がありますが、そうではありません。では、このマーク()の目的は何ですか? –

+0

私はあなたがこのドキュメントのバグを見つけたと思うのですが、実際には起こっていない限界を越えるとすぐにリセットが失敗するというヒントがあるようです。私は彼らが「最大限」の代わりに「最小限度」と言うことを意図していたと思う。 – john16384

+0

「最小限度」は意味をなさない。もちろん、 'reset()'を呼び出す前に多くのバイトを読み込む必要はありません。 – Holger

0

指定された制限でmarkを呼び出すと、指定した制限まで読み込んだ後にリセットをサポートする機能が要求されますが、それ以上の機能は否定していません。The specificationははっきり言う:

ただし、ストリームはresetが呼び出される前に、より多くreadlimitバイトストリームから読み込まれているすべての場合に任意のデータを覚えておく必要はありません。

"は必須ではありません。"は許可されていません "。この仕様には、常に動作するとは期待できないことが記載されているだけで、常に失敗すると予想できる内容は記載されていません。

BufferedInputStreamの場合、ボンネットの下で何が起こるか説明するのは簡単です。各BufferedInputStreamは容量があり、defaultは8192であり、常に現在のバッファ容量よりも多くのバイトをリセットすることができます。より高い制限を指定することにより、保証を満たすために、必要に応じてより大きなバッファを割り当てるようになります。

現在のバッファ容量をストリームに問い合わせることはできないため、指定した制限よりも多くのバイトを読み取らない限り、リセットが機能するという保証にのみ依存することができます。

それは、再現失敗作るためにあなたの一例を簡単に変更できます:

File resource = new File("beforeFix.txt");   
FileInputStream fileInputStream = new FileInputStream(resource); 
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream, 1); 
int i = bufferedInputStream.read(); 
bufferedInputStream.mark(1); 
i = bufferedInputStream.read(); 
i = bufferedInputStream.read(); 
bufferedInputStream.reset(); // will fail 
+0

「マーク位置が無効になる前に読み取ることができるバイトの最大限度」、常にOPの問題です無効です。 「** **無効になる可能性があります」とは読めません。 – john16384

+0

@ john16384:概念上、マーク*はあなたがそれに頼ることができないので無効です。別の質問があり、その結果はどのような結果になります。 [reset() '](https://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html#reset--)のドキュメントには、「If ...の数が'mark'が最後に呼び出されたときからストリームから読み取られたバイト数が最後の呼び出しで' mark'の引数より大きい場合、 'IOException' **がスローされる可能性があります。 "*が*"と保証されているわけではありません。... – Holger

+0

これは素晴らしい発見です。 – john16384

関連する問題