2010-01-11 65 views
5

Tôi đang cố gắng đọc một ký tự một dòng theo ký tự bằng cách sử dụng java.util.Scanner. Tuy nhiên tôi nhận được ngoại lệ này ":sử dụng java.util.Scanner để đọc byte tệp theo byte

Exception in thread "main" java.util.InputMismatchException: For input string: "contents of my file" 
    at java.util.Scanner.nextByte(Scanner.java:1861) 
    at java.util.Scanner.nextByte(Scanner.java:1814) 
    at p008.main(p008.java:18) <-- line where I do scanner.nextByte() 

Dưới đây là mã của tôi:

public static void main(String[] args) throws FileNotFoundException { 
    File source = new File("file.txt"); 
    Scanner scanner = new Scanner(source); 
    while(scanner.hasNext()) { 
     System.out.println((char)scanner.nextByte()); 
    } 
    scanner.close() 
} 

Có ai có bất kỳ ý tưởng như những gì tôi có thể làm sai

Edit: Tôi nhận ra tôi đã viết hasNext() thay vì hasNextByte() .Tuy nhiên nếu tôi làm điều đó nó không in ra bất cứ điều gì.

+6

Máy quét để phân tích cú pháp đầu vào ký tự. Tôi nghi ngờ bạn cần một InputStream. –

Trả lời

10

Tại sao bạn muốn sử dụng một máy quét để đọc một byte tập tin theo byte? mũi tên để vận chuyển thay đổi túi của bạn. (Nếu bạn thực sự cần một chiếc xe cút kít để đổi túi, hãy cho tôi biết để tôi có thể trở thành bạn của bạn).

Nhưng nghiêm túc: Lớp InputStream đọc byte từ tệp, đơn giản và đáng tin cậy và không làm gì khác.

Lớp scanner gần đây đã được đưa vào API Java để ví dụ sách giáo khoa có thể lấy dữ liệu ra khỏi tệp có ít đau hơn thường liên quan đến việc sử dụng tầng của new BufferedReader(new InputStream). Đặc sản của nó là nhập số và chuỗi từ các tệp đầu vào dạng tự do. Phương thức nextByte() thực sự đọc một hoặc một vài chữ số thập phân từ luồng đầu vào (nếu chúng ở đó) và chuyển đổi số do đó được quét thành một giá trị byte đơn.

Và nếu bạn đang đọc byte, tại sao bạn muốn xuất chúng dưới dạng char s? Số byte là không phải là ký tự và việc chuyển đổi tín hiệu ngang sẽ không thành công ở một số nơi. Nếu bạn muốn xem các giá trị của các byte đó, hãy in chúng ra như chúng và bạn sẽ thấy các số nguyên nhỏ giữa 0 và 255.

Nếu bạn muốn đọc char s từ một tệp, FileReader là lớp dành cho bạn .

+0

Tôi có một tệp văn bản bắt đầu bằng từ "Tóm tắt" (điều bất ngờ ..). Dù sao khi tôi thử đọc với: Scanner scanner = new Scanner (file); byte b = scanner.nextByte(); Tôi nhận được java.util.InputMismatchException. Tại sao tôi không thấy bất kỳ giá trị nào trong khoảng từ 0 đến 255, bạn có thể vui lòng trợ giúp không? Tệp là UTF-8. –

+0

Câu trả lời của tôi giải thích điều này, nhưng có lẽ không tốt lắm. Máy quét đọc và diễn giải đầu vào dạng văn bản, không phải byte cấp thấp! Hãy thử tạo một tệp có dòng đầu tiên đọc '1 10 100 1000 hello' và đọc với' Scanner.nextByte() '. Bạn sẽ đọc và trả thành công thành byte số 1, 10 và 100 nhưng bị ngoại lệ trên 1000 và (nếu bạn đọc quá khứ) trên "hello" vì đó không phải là giá trị có thể được biểu diễn bằng byte. –

2

Máy quét dành cho phân tích cú pháp dữ liệu văn bản - phương pháp nextByte() của chúng tôi hy vọng đầu vào sẽ bao gồm các chữ số (có thể có dấu hiệu trước).

Bạn có thể muốn sử dụng FileReader nếu bạn đang thực sự đọc dữ liệu văn bản hoặc FileInputStream nếu dữ liệu nhị phân của nó. Hoặc FileInputStream được bọc trong một InputStreamReader nếu bạn đang đọc văn bản có mã hóa ký tự cụ thể (không may, FileReader không cho phép bạn chỉ định mã hóa nhưng sử dụng mã hóa mặc định nền tảng ngầm, thường không tốt).

+0

Xin lỗi, ý của bạn là "phân tích dữ liệu văn bản" và "đọc dữ liệu văn bản"? –

+0

@KorayTugay: đọc có nghĩa là chỉ cần lấy bất cứ điều gì đến, một byte (hoặc ký tự) sau cái khác. Phân tích cú pháp có nghĩa là bạn mong đợi dữ liệu có một cấu trúc hoặc định dạng cụ thể, chẳng hạn như một chuỗi gồm các chữ số đứng trước dấu trừ tùy chọn, để bạn có thể hiểu nó dưới dạng một số. –

+0

Cảm ơn bạn đã bình luận. Vì vậy, phương pháp nextByte trong lớp Scanner là dành cho "chữ số đọc" chỉ? –

1

Khi xử lý sự cố Scanner, kiểm tra underlying I/O errors:

if(scanner.ioException() != null) { 
    throw scanner.ioException(); 
} 

Mặc dù tôi với những người khác - điều này có lẽ không phải là lớp học phù hợp với công việc. Nếu bạn muốn đầu vào byte, hãy sử dụng InputStream (trong trường hợp này là FileInputStream). Nếu bạn muốn đầu vào char, hãy sử dụng số Reader (ví dụ: InputStreamReader).

1

Scanner là tất cả về đọc văn bản phân cách (xem the docs).

nextByte sẽ tiếp tục đọc cho đến khi nó đến bất kỳ dấu phân cách nào bạn đã chỉ định (khoảng trắng theo mặc định) và sau đó thử chuyển đổi chuỗi đó thành byte.

Vì vậy, nếu bạn có 123 456 trong một tập tin, một cuộc gọi đến nextByte sẽ trở lại 123, không 49 (giá trị thập phân cho các nhân vật 1).


Nếu bạn muốn đọc từng byte, bạn có thể sử dụng FileInputStream.

Các vấn đề liên quan