-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCharacterStreams.java
More file actions
125 lines (111 loc) · 4.42 KB
/
Copy pathCharacterStreams.java
File metadata and controls
125 lines (111 loc) · 4.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package Phase8_PracticalAPIs.FileIO;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
/**
* Character Streams — Reader / Writer
* -----------------------------------
* Java 1.1 added Reader / Writer to address the fundamental mismatch
* between bytes and characters in modern encodings (UTF-8, UTF-16,
* GB-18030, ...). A single character can be 1-4 bytes, so reading
* "text" through an InputStream is wrong.
* <p>
*
* Reader — read characters
* ------------------------
* int read() -> next char 0..65535, -1 at EOF
* int read(char[] cbuf)
* int read(char[] cbuf, off, len)
* void close()
* <p>
*
* Writer — write characters
* -------------------------
* void write(int c)
* void write(char[] cbuf)
* void write(String s)
* void write(String s, off, len)
* void append(char c) -> chainable
* void flush()
* <p>
*
* The bridge classes
* ------------------
* InputStreamReader(InputStream, Charset) - bytes -> chars
* OutputStreamWriter(OutputStream, Charset) - chars -> bytes
* <p>
*
* Use these to wrap a byte stream when you need text from a non-File
* source (a Socket, stdin, an HTTP response).
* <p>
*
* Concrete impls
* --------------
* FileReader / FileWriter - file-flavoured (use the charset-aware
* constructors, NOT the default ones).
* StringReader / StringWriter - in-memory.
* CharArrayReader/Writer - in-memory, char[].
* PrintWriter - convenience formatting layer.
* <p>
*
* Charset trap
* ------------
* `new FileReader(file)` uses the platform default charset. That's a
* portability landmine. Prefer the Java 11+ charset-aware constructors
* or use Files.newBufferedReader(path, UTF_8).
*/
public class CharacterStreams {
public static void main(String[] args) throws IOException {
Path tmp = Files.createTempFile("char-demo-", ".txt");
section("1) FileWriter + UTF-8 — write text");
try (Writer out = new FileWriter(tmp.toFile(), StandardCharsets.UTF_8)) {
out.write("hello, file\n");
out.write("Java 21 ❤️ (heart emoji)\n");
out.append("appended line\n");
}
System.out.println("file size = " + Files.size(tmp) + " bytes");
section("2) FileReader + UTF-8 — read char by char");
try (Reader in = new FileReader(tmp.toFile(), StandardCharsets.UTF_8)) {
int c;
while ((c = in.read()) != -1) System.out.print((char) c);
}
section("3) FileReader + buffer (fast)");
char[] buf = new char[256];
try (Reader in = new FileReader(tmp.toFile(), StandardCharsets.UTF_8)) {
int n = in.read(buf);
System.out.println("read " + n + " chars; first 5 = '"
+ new String(buf, 0, Math.min(5, n)) + "'");
}
section("4) The byte-to-char bridge: InputStreamReader");
// Reading text from a NON-file InputStream (here, a byte array
// that we pretend came from a network socket).
byte[] body = "fetched from net".getBytes(StandardCharsets.UTF_8);
try (Reader r = new InputStreamReader(new java.io.ByteArrayInputStream(body), StandardCharsets.UTF_8)) {
int n = r.read(buf);
System.out.println("decoded text = '" + new String(buf, 0, n) + "'");
}
section("5) The char-to-byte bridge: OutputStreamWriter");
java.io.ByteArrayOutputStream bytes = new java.io.ByteArrayOutputStream();
try (Writer w = new OutputStreamWriter(bytes, StandardCharsets.UTF_8)) {
w.write("café ☕");
}
System.out.println("encoded UTF-8 bytes = " + bytes.size());
section("6) StringReader / StringWriter — in-memory");
StringWriter sw = new StringWriter();
sw.write("hello, ");
sw.write("world");
sw.append('!');
System.out.println("StringWriter holds: " + sw);
try (StringReader sr = new StringReader("xyz abc")) {
int n = sr.read(buf);
System.out.println("read from StringReader: '" + new String(buf, 0, n) + "'");
}
Files.deleteIfExists(tmp);
section("done");
}
private static void section(String title) {
System.out.println();
System.out.println("=== " + title + " ===");
}
}