openplanning

Hướng dẫn và ví dụ Java InputStreamReader

Xem thêm các chuyên mục:

Hãy theo dõi chúng tôi trên Fanpage để nhận được thông báo mỗi khi có bài viết mới. Facebook

1- InputStreamReader

InputStreamReader là một lớp con của Reader, nó là một cầu nối cho phép bạn chuyển một byte stream thành một character stream, hay nói cách khác nó cho phép bạn chuyển đổi một InputStream thành một Reader.
Mẹo: Để chuyển một "InputStream" thành một "Reader" bạn chỉ cần nối 2 từ này với nhau để thành từ "InputStreamReader" bạn sẽ có được lời giải của vấn đề.
InputStreamReader​ constructors

InputStreamReader​(InputStream in)    

InputStreamReader​(InputStream in, String charsetName)    

InputStreamReader​(InputStream in, Charset cs)    

InputStreamReader​(InputStream in, CharsetDecoder dec)

2- UTF-16 InputStreamReader

UTF-16 là một mã hoá (encoding) khá phổ biến đối với văn bản tiếng Trung Quốc hoặc tiếng Nhật. Trong ví dụ này chúng ta sẽ phân tích làm thế nào InputStreamReader đọc được các văn bản UTF-16.
Trước hết, hãy xem file văn bản tiếng Nhật dưới đây, nó được mã hoá UTF-16:
utf16-file-with-bom.txt

JP日本-八洲
Code đầy đủ của ví dụ:
InputStreamReader_UTF16_Ex1.java

package org.o7planning.inputstreamreader.ex;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;

public class InputStreamReader_UTF16_Ex1 {

    // A file in UTF-16.
    private static final String fileURL = "https://s3.o7planning.com/txt/utf16-file-with-bom.txt";
    
    public static void main(String[] args) throws MalformedURLException, IOException {
        System.out.println(" --- Characters in Character Stream (InputStreamReader) ---");
        readAs_UTF16_Character_Stream();

        System.out.println();
        System.out.println(" --- Bytes in UTF-16 file ---");
        readAs_Binary_Stream();
    }

    private static void readAs_UTF16_Character_Stream() throws MalformedURLException, IOException {

        InputStream is = new URL(fileURL).openStream();
        InputStreamReader isr = new InputStreamReader(is, "UTF-16");

        int charCode;
        while ((charCode = isr.read()) != -1) { // Read each character.
            System.out.println((char) charCode + "  " + charCode);
        }
        isr.close();
    }

    private static void readAs_Binary_Stream() throws MalformedURLException, IOException {

        InputStream is = new URL(fileURL).openStream();

        int byteValue;
        while ((byteValue = is.read()) != -1) { // Read each byte.
            System.out.println((char) byteValue + "  " + byteValue);
        }
        is.close();
    }
}
Output:

 --- Characters in Character Stream (InputStreamReader) ---
J  74
P  80
日  26085
本  26412
-  45
八  20843
洲  27954

 --- Bytes in UTF-16 file ---
þ  254
ÿ  255
  0
J  74
  0
P  80
e  101
å  229
g  103
,  44
  0
-  45
Q  81
k  107
m  109
2  50
Tạo ra một đối tượng InputStreamReader với mã hoá UTF-16 và bao bọc một đối tượng InputStream:

String url = "https://s3.o7planning.com/txt/utf16-file-with-bom.txt";

InputStream is = new URL(url).openStream();
InputStreamReader isr = new InputStreamReader(is, "UTF-16");
Hình ảnh dưới đây cho thấy các bytes trong file UTF-16. Hai bytes đầu tiên (254, 255) được sử dụng để đánh dấu rằng nó bắt đầu của một văn bản UTF-16.
UTF-16 InputStreamReader đọc 2 bytes đầu tiên để xác định kiểu mã hoá của văn bản, và biết rằng nó đang làm việc với một văn bản UTF-16. Nó ghép 2 bytes liên tiếp để tạo thành một ký tự...

3- UTF-8 InputStreamReader

UTF-8 là một mã hoá (encoding) phổ biến nhất thế giới, nó có thể mã hoá mọi chữ viết trên thế giới bao gồm cả ký tự của Trung Quốc và ký tự của Nhật Bản. Bây giờ chúng ta sẽ phân tích làm thế nào InputStreamReader đọc được các văn bản UTF-8.
Trước hết, hãy xem file văn bản tiếng Nhật dưới đây, nó được mã hoá UTF-8:
utf8-file-without-bom.txt

JP日本-八洲
Code đầy đủ của ví dụ:
InputStreamReader_UTF8_Ex1.java

package org.o7planning.inputstreamreader.ex;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;

public class InputStreamReader_UTF8_Ex1 {

    // A file with UTF-8 encoding (And without BOM (Byte Order Mark)).
    private static final String fileURL = "https://s3.o7planning.com/txt/utf8-file-without-bom.txt";
    
    public static void main(String[] args) throws MalformedURLException, IOException {
        System.out.println(" --- Characters in Character Stream (InputStreamReader) ---");
        readAs_UTF8_Character_Stream();

        System.out.println();
        System.out.println(" --- Bytes in UTF-8 file ---");
        readAs_Binary_Stream();
    }

    private static void readAs_UTF8_Character_Stream() throws MalformedURLException, IOException {
        
        InputStream is = new URL(fileURL).openStream();
        InputStreamReader isr = new InputStreamReader(is, "UTF-8");

        int charCode;
        while ((charCode = isr.read()) != -1) { // Read each character.
            System.out.println((char) charCode + "  " + charCode);
        }
        isr.close();
    }

    private static void readAs_Binary_Stream() throws MalformedURLException, IOException {

        InputStream is = new URL(fileURL).openStream();

        int byteValue;
        while ((byteValue = is.read()) != -1) { // Read each byte.
            System.out.println((char) byteValue + "  " + byteValue);
        }
        is.close();
    }
}
Output:

 --- Characters in Character Stream (InputStreamReader) ---
J  74
P  80
日  26085
本  26412
-  45
八  20843
洲  27954

 --- Bytes in UTF-8 file ---
J  74
P  80
æ  230
—  151
¥  165
æ  230
œ  156
¬  172
-  45
å  229
…  133
«  171
æ  230
´  180
²  178
Tạo ra một đối tượng InputStreamReader với mã hoá UTF-8 và bao bọc một đối tượng InputStream:

String url = "https://s3.o7planning.com/txt/utf8-file-without-bom.txt";

InputStream is = new URL(url).openStream();
InputStreamReader isr = new InputStreamReader(is, "UTF-8");
Hình ảnh dưới đây cho thấy các bytes trong file UTF-8:
Mã hoá UTF-8 phức tạp hơn rất nhiều so với UTF-16, nó cần 1, 2, 3 hoặc 4 bytes để lưu trữ một ký tự, điều này phụ thuộc vào mã của ký tự.
Number of bytes   From To Byte 1 Byte 2 Byte 3 Byte 4
1 U+0000 0 U+007F 127 0xxxxxxx  
2 U+0080 128 U+07FF 2047 110xxxxx 10xxxxxx  
3 U+0800 2048 U+FFFF 65535 1110xxxx 10xxxxxx 10xxxxxx  
4 U+10000 65536 U+10FFFF 1114111 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
Hình ảnh dưới đây là một ví dụ cho thấy cách UTF-8 InputStreamReader biến 3 bytes của UTF-8 thành 1 ký tự 2 bytes của Java:

Xem thêm các chuyên mục: