2011-12-22 33 views
10

Tôi đang học cách sử dụng InputStream. Tôi đã cố gắng sử dụng nhãn hiệu cho BufferedInputStream, nhưng khi tôi cố gắng để thiết lập lại tôi có những trường hợp ngoại lệ:Đánh dấu luồng đầu vào được đánh dấu là giới hạn đọc

java.io.IOException: Resetting to invalid mark 

Tôi nghĩ rằng điều này có nghĩa rằng dấu ấn của tôi đọc giới hạn được thiết lập sai. Tôi thực sự không biết cách thiết lập giới hạn đọc trong mark(). Tôi đã thử cách này:

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

Điều này cũng sai.

is.mark(16); 

Điều này cũng có cùng ngoại lệ. Tôi làm cách nào để biết giới hạn đọc được đặt là gì? Vì tôi sẽ đọc các kích thước tệp khác nhau từ luồng đầu vào.

+2

Việc cá nhân của tôi? Đừng dùng dấu - trong khi tôi chắc chắn có một cái, tôi vẫn chưa tìm được lý do chính đáng cho nó. Thông thường, đó là một dấu hiệu của việc xử lý kém ở nơi đầu tiên. Tôi có xu hướng nghĩ về một luồng không phải là luồng trừ khi tôi đang xử lý hình thức thô nhất mà nó có. Tôi muốn có một wrapper chặt chẽ xung quanh nó được thông tin của nó, gói nó lên, và gửi gói đó để xử lý một nơi nào đó trong ứng dụng. – corsiKa

+0

@glowcoder Cảm ơn nhận xét của bạn. Như tôi đã nói trước đó, tôi mới làm việc với InputStream. Tôi đã thực sự cố gắng sử dụng luồng đầu vào hai lần. Tôi nghĩ rằng đây là cách để làm điều đó. Đặt dấu và đặt lại. Bạn có gợi ý nào khác về cách đạt được điều này không? –

+3

Đánh dấu hoạt động như thế này. Giả sử luồng đầu vào của bạn sẽ kết thúc là 'A B C D E'. Bạn xử lý 'A B' cho đến nay. (Hãy nhớ rằng, bạn không biết những gì 'hạ lưu' được nêu ra.) Bạn đánh dấu nó. Sau đó bạn đọc thêm một số, và bạn nhận được 'C D E'. Bạn nhìn vào nó và nói "Đợi đã, tôi không thể xử lý' C D E' trong chế độ này! " vì lý do gì. Vì vậy, bạn nói "Tôi thực sự muốn tôi có thể quay trở lại để xử lý' C D E' một lần nữa ... mà bạn có thể, vì bạn 'mark()' ed nó.Bạn chỉ cần 'reset()' để đưa luồng trở lại vị trí của nó khi bạn đánh dấu nó và bạn có thể đọc lại nó như bạn đã có trước đây. – corsiKa

Trả lời

0

Giá trị bạn chuyển đến mark() là số tiền mà bạn cần phải đặt lại. nếu bạn cần đặt lại ở đầu luồng, bạn sẽ cần bộ đệm lớn như toàn bộ luồng. điều này có lẽ không phải là một thiết kế tuyệt vời vì nó sẽ không quy mô tốt cho các luồng lớn. nếu bạn cần đọc luồng hai lần và bạn không biết nguồn dữ liệu (ví dụ: nếu đó là tệp, bạn có thể chỉ cần mở lại), thì có thể bạn nên sao chép tệp đó vào tệp tạm thời để bạn có thể đọc nó theo ý muốn.

+0

cảm ơn câu trả lời của bạn, i đã lên kế hoạch thiết lập lại nó ngay từ đầu. Nhưng bây giờ tôi nghĩ rằng nó không phải là một ý tưởng tốt. Khi u nói tôi nên sao chép nó vào tập tin tạm thời, làm u có nghĩa là tôi cần phải lưu trữ nó một nơi nào đó trong thư mục của tôi đầu tiên trước khi sử dụng nó? –

+0

@NurAini - vâng, tạo một tệp tạm thời, sao chép luồng vào đó, sau đó bạn có thể đọc lại tệp tạm thời đó bao nhiêu lần tùy thích. – jtahlborn

6

mark đôi khi hữu ích nếu bạn cần kiểm tra một vài byte ngoài những gì bạn đã đọc để quyết định điều cần làm tiếp theo, sau đó bạn đặt lại dấu và gọi thường trình mong muốn con trỏ tệp ở đầu của phần logic đó của đầu vào. Tôi không nghĩ rằng nó thực sự là dành cho nhiều người khác.

Nếu bạn nhìn vào javadoc cho BufferedInputStream nó nói

Các hoạt động đánh dấu nhớ một điểm trong dòng đầu vào và các hoạt động thiết lập lại gây ra tất cả các byte đọc kể từ khi hoạt động đánh dấu gần nhất để được đọc lại trước khi mới byte được lấy từ luồng đầu vào chứa.

Điều quan trọng cần nhớ ở đây là khi bạn đánh dấu một vị trí trong dòng, nếu bạn liên tục đọc vượt quá chiều dài đáng kể, đánh dấu sẽ không còn giá trị, và cuộc gọi để thiết lập lại sẽ thất bại. Vì vậy, đánh dấu là tốt cho các tình huống cụ thể và không sử dụng nhiều trong các trường hợp khác.

+0

cảm ơn nhận xét của bạn. khi bạn nói rằng 'nếu bạn tiếp tục đọc và bộ đệm cần được nạp lại'. Điều đó có xảy ra vì tôi đã sử dụng BufferedInputStream không? –

+0

Có, tuy nhiên, các luồng io không bị chặn không hỗ trợ đánh dấu và đặt lại. – Bill

1

Điều này sẽ đọc 5 lần từ cùng một 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(); 
} 
Các vấn đề liên quan