-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDataStreams.java
More file actions
110 lines (99 loc) · 3.84 KB
/
Copy pathDataStreams.java
File metadata and controls
110 lines (99 loc) · 3.84 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
package Phase8_PracticalAPIs.FileIO;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
/**
* Data Streams — DataInputStream / DataOutputStream
* --------------------------------------------------
* DECORATORS on top of byte streams that read and write Java's PRIMITIVE
* TYPES in a portable, fixed-width binary format:
* <p>
*
* int (4 bytes), long (8), short (2), byte (1),
* float (4), double (8), boolean (1), char (2),
* "modified UTF-8" strings via writeUTF / readUTF.
* <p>
*
* Byte order is BIG-ENDIAN, regardless of platform.
* <p>
*
* Why this exists
* ---------------
* Without DataStreams you'd have to encode/decode each primitive by
* hand (shifts, masks, byte arrays). DataStreams give you the same
* format any other Java program will agree on.
* <p>
*
* Pattern
* -------
* try (var out = new DataOutputStream(new FileOutputStream(f))) {
* out.writeInt(42);
* out.writeUTF("hello");
* }
* try (var in = new DataInputStream(new FileInputStream(f))) {
* int n = in.readInt();
* String s = in.readUTF();
* }
* <p>
*
* Caveats
* -------
* 1. readUTF / writeUTF use Java's MODIFIED UTF-8 (not standard UTF-8).
* For interop with other languages, use a Reader with UTF_8 or a
* proper protocol library.
* 2. The format is positional. There's no schema, no field names,
* and no versioning. For real data, prefer JSON / Protobuf /
* Avro / Java serialization.
* 3. End-of-stream — methods like readInt throw EOFException (not -1).
*/
public class DataStreams {
public static void main(String[] args) throws IOException {
Path tmp = Files.createTempFile("data-demo-", ".bin");
section("1) Write a few primitives + a UTF string");
try (OutputStream raw = new FileOutputStream(tmp.toFile());
DataOutputStream out = new DataOutputStream(raw)) {
out.writeInt(42);
out.writeLong(1234567890123L);
out.writeDouble(3.1415926535);
out.writeBoolean(true);
out.writeUTF("hello, data");
}
System.out.println("file size = " + Files.size(tmp) + " bytes");
section("2) Read them back in the SAME ORDER");
try (InputStream raw = new FileInputStream(tmp.toFile());
DataInputStream in = new DataInputStream(raw)) {
int a = in.readInt();
long b = in.readLong();
double c = in.readDouble();
boolean d = in.readBoolean();
String s = in.readUTF();
System.out.println("int=" + a + ", long=" + b + ", double=" + c
+ ", bool=" + d + ", text='" + s + "'");
}
section("3) Reading past EOF throws EOFException");
try (DataInputStream in = new DataInputStream(new FileInputStream(tmp.toFile()))) {
try {
while (true) in.readInt();
} catch (EOFException eof) {
System.out.println("expected: EOFException after reading the bytes");
}
}
section("4) Loop-write + loop-read using a sentinel");
Path tmp2 = Files.createTempFile("data-loop-", ".bin");
try (DataOutputStream out = new DataOutputStream(new FileOutputStream(tmp2.toFile()))) {
for (int i = 1; i <= 5; i++) out.writeInt(i * i);
}
try (DataInputStream in = new DataInputStream(new FileInputStream(tmp2.toFile()))) {
try {
while (true) System.out.println(" square = " + in.readInt());
} catch (EOFException ignored) { /* done */ }
}
Files.deleteIfExists(tmp);
Files.deleteIfExists(tmp2);
section("done");
}
private static void section(String title) {
System.out.println();
System.out.println("=== " + title + " ===");
}
}