Hướng dẫn và ví dụ Java OutputStreamWriter
Xem thêm các chuyên mục:

Là một website được viết trên công nghệ web Flutter vì vậy hỗ trợ rất tốt cho người học, kể cả những người học khó tính nhất.
Hiện tại website đang tiếp tục được cập nhập nội dung cho phong phú và đầy đủ hơn. Mong các bạn nghé thăm và ủng hộ website mới của chúng tôi.


OutputStreamWriter là một lớp con của Writer, 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 OutputStream thành một Writer

Mẹo: Để chuyển một "OutputStream" thành một "Writer" bạn chỉ cần nối 2 từ này với nhau để thành từ "OutputStreamWriter" bạn sẽ có được lời giải của vấn đề.

OutputStreamWriter constructors
OutputStreamWriter(OutputStream out)
OutputStreamWriter(OutputStream out, String charsetName)
OutputStreamWriter(OutputStream out, Charset cs)
OutputStreamWriter(OutputStream out, CharsetEncoder enc)
Ngoài các phương thức được thừa kế từ lớp cha, OutputStreamWriter có một vài phương thức của riêng nó.
Method | Description |
String getEncoding() | Trả về tên của mã hóa ký tự đang được sử dụng bởi OutputStreamWriter. |
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 để ghi một file với mã hoá UTF-16.
Và đây là nội dung cần ghi vào file:
JP日本-八洲
Trong ví dụ này chúng ta sử dụng UTF-16 OutputStreamWriter để ghi các ký tự vào một file, sau đó sử dụng FileInputStream để đọc từng byte dữ liệu của file đó.
OutputStreamWriter_UTF16_Ex1.java
package org.o7planning.outputstreamwriter.ex;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
public class OutputStreamWriter_UTF16_Ex1 {
private static final String filePath = "/Volumes/Data/test/utf16-file-out.txt";
public static void main(String[] args) throws IOException {
System.out.println(" --- Write UTF-16 File --- ");
write_UTF16_Character_Stream();
System.out.println(" --- Read File as Binary Stream --- ");
readAs_Binary_Stream();
}
private static void write_UTF16_Character_Stream() throws IOException {
File outFile = new File(filePath);
outFile.getParentFile().mkdirs(); // Create parent folder.
// Create OutputStream to write a file.
OutputStream os = new FileOutputStream(outFile);
// Create a OutputStreamWriter
OutputStreamWriter osw = new OutputStreamWriter(os, StandardCharsets.UTF_16);
String s = "JP日本-八洲";
osw.write(s);
osw.close();
}
private static void readAs_Binary_Stream() throws IOException {
InputStream is = new FileInputStream(filePath);
int byteValue;
while ((byteValue = is.read()) != -1) { // Read byte by byte.
System.out.println((char) byteValue + " " + byteValue);
}
is.close();
}
}
Output:
--- Write UTF-16 File ---
--- Read File as Binary Stream ---
þ 254
ÿ 255
0
J 74
0
P 80
e 101
å 229
g 103
, 44
0
- 45
Q 81
k 107
m 109
2 50
Trong Java, kiểu dữ liệu char có kích thước 2 bytes, và UTF-16 được sử dụng để mã hoá kiểu String. Hình ảnh dưới đây cho thấy các ký tự trên OutputStreamWriter:

Phân tích các bytes trên file vừa được tạo ra cho thấy: 2 bytes đầu tiên là (254, 255) được sử dụng để đánh dấu rằng đây là một văn bản được mã hoá UTF-16, chúng còn được gọi là BOM (Byte Order Mark), còn các bytes tiếp theo giống với các bytes trên OutputStreamWriter.

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ắt đầu từ Java5, UTF-8 là mã hoá mặc định khi đọc và ghi file.
Các file UTF-8 được tạo ra bởi Java sẽ không có BOM (Byte Order Mark) (Các bytes đầu tiên của file để đánh dấu rằng đây là một file UTF-8).
OutputStreamWriter_UTF8_Ex1.java
package org.o7planning.outputstreamwriter.ex;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
public class OutputStreamWriter_UTF8_Ex1 {
private static final String filePath = "/Volumes/Data/test/utf8-file-out.txt";
public static void main(String[] args) throws IOException {
System.out.println(" --- Write UTF-8 File --- ");
write_UTF8_Character_Stream();
System.out.println(" --- Read File as Binary Stream --- ");
readAs_Binary_Stream();
}
private static void write_UTF8_Character_Stream() throws IOException {
File outFile = new File(filePath);
outFile.getParentFile().mkdirs(); // Create parent folder.
// Create OutputStream to write a file.
OutputStream os = new FileOutputStream(outFile);
// Create a OutputStreamWriter
OutputStreamWriter osw = new OutputStreamWriter(os, StandardCharsets.UTF_8);
String s = "JP日本-八洲";
osw.write(s);
osw.close();
}
private static void readAs_Binary_Stream() throws IOException {
InputStream is = new FileInputStream(filePath);
int byteValue;
while ((byteValue = is.read()) != -1) { // Read byte by byte.
System.out.println((char) byteValue + " " + byteValue);
}
is.close();
}
}
Output:
--- Write UTF-8 File ---
--- Read File as Binary Stream ---
J 74
P 80
æ 230
151
¥ 165
æ 230
156
¬ 172
- 45
å 229
133
« 171
æ 230
´ 180
² 178
Trong Java, kiểu dữ liệu char có kích thước 2 bytes, và UTF-16 được sử dụng để mã hoá kiểu String. Hình ảnh dưới đây cho thấy các ký tự trên OutputStreamWriter:

UTF-8 được mã hoá phức tạp hơn khá nhiều so với UTF-16, nó sử dụng 1, 2, 3 hoặc 4 bytes để lưu trữ một ký tự. Phân tích chi tiết các bytes trên file UTF-8 vừa được tạo ra cho thấy rõ điều đó.
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 |
Ví dụ ký tự "日" có mã số là 26085 thuộc phạm vi [2048,65535], UTF-8 sẽ cần 3 bytes để lưu trữ nó.
