2011-12-22 2 views
10

Sto imparando come utilizzare un InputStream. Stavo cercando di utilizzare il marchio per BufferedInputStream, ma quando provo a resettare ho queste eccezioni:Limite di lettura del limite del flusso di ingresso bufferizzato

java.io.IOException: Resetting to invalid mark 

Penso che questo significa che la mia lettura del segno limite è fissato male. In realtà non so come impostare il limite di lettura in mark(). Ho provato così:

is = new BufferedInputStream(is); 
is.mark(is.available()); 

Anche questo è sbagliato.

is.mark(16); 

Anche questa genera la stessa eccezione. Come faccio a sapere quale limite di lettura devo impostare? Poiché leggerò diverse dimensioni di file dallo stream di input.

+2

Il mio personale? Non usare il marchio - mentre sono sicuro che ce ne sia uno, devo ancora trovare una buona ragione per questo. Spesso, in primo luogo, è un segno di scarsa maneggevolezza. Tendo a pensare a un flusso non come un flusso a meno che non mi occupi della forma più grezza che ha. Preferirei avere un involucro stretto attorno ad esso che ottenga le sue informazioni, le impacchetta e invia quel pacchetto per l'elaborazione da qualche parte nell'app. – corsiKa

+0

@glowcoder Grazie per il tuo commento. Come ho detto prima, sono nuovo nel lavorare con InputStream. In realtà stavo cercando di utilizzare il flusso di input due volte. Pensavo che questo fosse il modo di farlo. Segnare e resettare. Avete altri suggerimenti su come ottenere questo? –

+3

Mark funziona in questo modo. Diciamo che il tuo flusso di input finirebbe per essere "A B C D E". Elabora 'A B' finora. (Ricorda, non sai ancora cosa sia "downstream"). Lo marchi. Poi leggi di più e ottieni 'C D E'. Lo guardi e dici "Aspetta, non posso elaborare' C D E' in questa modalità! " per qualsiasi ragione. Quindi tu dici "Vorrei davvero poter tornare ad elaborare' C D E' di nuovo ... quale puoi, dal momento che tu lo contrassegni() ".Devi semplicemente reimpostare() per riportare lo stream su dove era quando lo hai marcato e puoi leggerlo di nuovo come avresti fatto prima. – corsiKa

risposta

0

Il valore che si passa a mark() è l'importo a ritroso che è necessario ripristinare. se hai bisogno di resettare all'inizio dello stream, avrai bisogno di un buffer grande quanto l'intero stream. questo probabilmente non è un grande progetto in quanto non si adatta bene ai grandi flussi. se hai bisogno di leggere il flusso due volte e non sai la fonte dei dati (ad esempio se si tratta di un file, potresti semplicemente riaprirlo), dovresti probabilmente copiarlo in un file temporaneo in modo da poter leggerlo a volontà.

+0

grazie per la tua risposta, i stava progettando di resettarlo all'inizio. Ma ora penso che non sia una buona idea. Quando hai detto che dovrei copiarlo in un file temporaneo, vuoi dire che ho bisogno di memorizzarlo da qualche parte nella mia cartella prima di usarlo? –

+0

@NurAini - Sì, creare un file temporaneo, copiare lo stream in esso, quindi è possibile rileggere quel file temporario tutte le volte che è necessario. – jtahlborn

6

mark è talvolta utile se è necessario esaminare alcuni byte oltre a ciò che è stato letto per decidere cosa fare in seguito, quindi ripristinare il segno e chiamare la routine che si aspetta che il puntatore del file sia all'inizio di quella parte logica dell'input. Non penso che sia davvero destinato a molto altro.

Se si guarda alla javadoc per BufferedInputStream si dice

L'operazione di contrassegno si ricorda di un punto nel flusso di input e l'operazione di ripristino fa sì che tutti i byte letti dal momento che la più recente operazione di marchio da rileggere prima di nuovo i byte sono presi dal flusso di input contenuto.

La cosa fondamentale da ricordare è, una volta segnare un punto nel flusso, se si continua a leggere oltre la lunghezza marcato, il marchio non sarà più valida, e la chiamata a ripristinare falliranno. Quindi il marchio è buono per situazioni specifiche e non è molto utile in altri casi.

+0

grazie per il tuo commento. quando hai detto che "se continui a leggere e il buffer deve essere riempito". Sta succedendo perché ho usato BufferedInputStream? –

+0

Sì, tuttavia, i flussi io senza buffer non supportano il mark e il reset. – Bill

1

Questo leggerà 5 volte dallo stesso BufferedInputStream.

for (int i=0; i<5; i++) { 
    inputStream.mark(inputStream.available()+1); 
    // Read from input stream 
    Thumbnails.of(inputStream).forceSize(160, 160).toOutputStream(out); 
    inputStream.reset(); 
}