Repository navigation
Expand file tree
/
Copy pathChapter09.java
More file actions
319 lines (267 loc) · 10.5 KB
/
Copy pathChapter09.java
File metadata and controls
319 lines (267 loc) · 10.5 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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
import ch09.Employee;
import ch09.IoUtils;
import ch09.Point;
import ch09.PointDisk;
import org.junit.Test;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class Chapter09 {
@Test
public void ex01() throws IOException {
Path source = Paths.get("docs/ch09/music.mp3");
Path target = Paths.get("docs/ch09/music.target.mp3");
try (InputStream in = Files.newInputStream(source);
OutputStream out = Files.newOutputStream(target);) {
IoUtils.copyWithTemp(in, out);
}
}
@Test
public void ex02() throws IOException {
Path source = Paths.get("docs/ch09/alice.txt");
Path target = Paths.get("docs/ch09/alice.toc");
// 파일을 한줄씩 읽으면서 라인 번호를 가져올 수 있는 java.io.LineNumberReader
try (LineNumberReader reader = new LineNumberReader(Files.newBufferedReader(source, StandardCharsets.UTF_8));) {
// Map<라인번호, List<단어>> 로 변환한다.
Map<Integer, List<String>> mapFrom = reader.lines()
// 비어있는 라인 필터
.filter(v -> !v.trim().isEmpty())
// 모두 소문자로 변경
.map(String::toLowerCase)
// Map<라인번호, List<문자>> 으로 변경
.collect(Collectors.toMap(
// 키를 라인 번호로 사용
t -> reader.getLineNumber(),
// 값를 String -> List<String> 으로 사용 (빈문자 필터, 단어 중복 제거)
t -> Arrays.stream(t.split("\\PL+")).filter(v -> !v.trim().isEmpty()).distinct()
.collect(Collectors.toList())));
// Map<라인번호, List<단어>> 를 Map<단어, List<라인번호>> 로 변경한다.
Map<String, List<Integer>> mapTo = mapFrom.entrySet().stream()
// Map<라인번호, List<단어> -> Stream<Map<단어, 라인번호>> 로 쪼갠다.
.flatMap(e -> e.getValue().stream().map(v -> new AbstractMap.SimpleImmutableEntry<>(e.getKey(), v)))
// 단어로 그룹핑 (키 = 단어, 값 = List<라인번호>)
.collect(Collectors.groupingBy(AbstractMap.SimpleImmutableEntry::getValue,
Collectors.mapping(AbstractMap.SimpleImmutableEntry::getKey, Collectors.toList())));
// 파일로 출력
try (PrintWriter pw = new PrintWriter(Files.newBufferedWriter(target, StandardCharsets.UTF_8));) {
mapTo.forEach((k, v) -> {
pw.println(k + " = " + v.stream().map(Object::toString).collect(Collectors.joining(", ")));
});
}
}
}
// 텍스트를 담고 잇는 파일을 읽은 후 단어 대부분이 영어로 되어 있다고 가정하고 인코딩이 아스키, ISO-8859-1, UTF-8, UTF-16 중 어느 것인지 추측하는 프로그램을 작성하라.
// UTF-16일 때는 사용한 바이트 순서도 추측해야 한다.
@Test
public void ex03() throws IOException {
try (BufferedReader reader = Files.newBufferedReader(Paths.get("docs/ch09/encode.txt"), StandardCharsets.UTF_8);) {
reader.lines().forEach(v -> {
System.out.println(Arrays.toString(v.codePoints().toArray()));
});
}
}
@Test
public void ex04a() throws IOException {
try (Scanner scanner = new Scanner(Paths.get("docs/ch09/catalina.out"));) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
}
}
}
@Test
public void ex04b() throws IOException {
try (BufferedReader reader = Files.newBufferedReader(Paths.get("docs/ch09/catalina.out"));) {
String line = null;
while ((line = reader.readLine()) != null) {
}
}
}
@Test
public void ex04c() throws IOException {
try (BufferedReader reader = Files.newBufferedReader(Paths.get("docs/ch09/catalina.out"));) {
reader.lines().forEach(v -> {
});
}
}
@Test
public void ex06() throws IOException {
Path path = Paths.get("docs/ch09/mario.bmp");
try (RandomAccessFile raf = new RandomAccessFile(path.toFile(), "rw");) {
// BMP 파일인지 검증
int header = raf.readUnsignedShort();
if (header != 0x424D) {
System.err.println(path + " is not bitmap");
}
// 이미지 데이터의 위치를 찾는다.
raf.seek(0x000A);
int offset = raf.read() | (raf.read() << 8) | (raf.read() << 16) | (raf.read() << 24);
// 1바이트씩 이동하면서 색 반전
raf.seek(offset);
int read = -1;
while ((read = raf.read()) != -1) {
raf.seek(raf.getFilePointer() - 1);
raf.write(255 - read);
}
}
}
@Test
public void ex08() throws IOException {
// 압축할 대상 디렉터리
Path path = Paths.get("D:\\develoment\\javaimpatient");
// 만들어지는 zip 파일
Path zipPath = Paths.get("D:\\ch09-ex08.zip");
try (ZipOutputStream out = new ZipOutputStream(Files.newOutputStream(zipPath));) {
// 모든 하위 목록 가져옴
try (Stream<Path> entries = Files.walk(path);) {
entries.filter(p -> !Files.isDirectory(p)).forEach(p -> {
try {
out.putNextEntry(new ZipEntry(path.relativize(p).toString()));
Files.copy(p, out);
out.closeEntry();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
}
}
}
@Test
public void ex09() throws IOException {
String http = "http://httpbin.org/basic-auth/user/passwd";
String username = "user";
String password = "passwd";
String input = username + ":" + password;
String encoding = Base64.getEncoder().encodeToString(input.getBytes(StandardCharsets.UTF_8));
URL url = new URL(http);
URLConnection conn = url.openConnection();
conn.setRequestProperty("Authorization", "Basic " + encoding);
conn.connect();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));) {
reader.lines().forEach(System.out::println);
}
}
@Test
public void ex10a() {
// (a) find
String s = "antop name 10.12 is aaa! antop is+33 -15";
String regex = "[+-]?[0-9]+";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(s);
List<Integer> list = new ArrayList<>();
while (matcher.find()) {
list.add(Integer.parseInt(matcher.group()));
}
System.out.println(list);
// [10, 12, 33, -15]
}
@Test
public void ex10b() {
// (b) split
String s = "antop name 10.12 is aaa! antop is+33 -15";
String regex = "[^+\\-0-9]";
Pattern pattern = Pattern.compile(regex);
List<String> list = Arrays.stream(pattern.split(s)).filter(v -> !v.trim().isEmpty()).collect(Collectors.toList());
System.out.println(list);
// [10, 12, +33, -15]
}
// 11. 정규 표현식을 사용해 /home/cay/myfile.txt 같은 절대 경로 또는 상대 경로에서 디렉터리 경로 이름들(문자열의 배열), 파일 이름, 파일 확장자를 추출하라.
@Test
public void ex11() throws IOException {
class FileInfo {
// 디렉터리 경로 이름들
private String[] directories;
// 파일 이름
private String name;
// 확장자
private String extension;
@Override
public String toString() {
return "FileInfo{" + "directories=" + Arrays.toString(directories) + ", name='" + name + '\'' + ", extension='" + extension + '\'' + '}';
}
}
// 찾을 루트 경로
Path root = Paths.get(".");
// OS 에서 사용하는 경로 구분자
String separator = Pattern.quote(File.separator);
// 디렉터리 경로 + 파일 정규 표현식
Pattern pathPattern = Pattern.compile("(?<directory>([^+]+" + separator + ")+)(?<name>[^+]+$)");
// 파일 이름 + 확장자 정규 표현식식
Pattern fileNamePattern = Pattern.compile("(?<name>[^+]+)(?<ext>\\.[^.]+$)");
try (Stream<Path> entries = Files.walk(root);) {
List<FileInfo> result = entries
// 파일만 걸러낸다.
.filter(p -> !Files.isDirectory(p))
// 파일 경로를 정규화 한다. (/home/antop/./doc/../app -> /home/antop/app)
.map(p -> p.toAbsolutePath().normalize()).map(p -> {
FileInfo f = new FileInfo();
Matcher m1 = pathPattern.matcher(p.toString());
if (m1.matches()) { // 디렉터리 + 파일명으로 분리
String directory = m1.group("directory");
String fileName = m1.group("name");
// 디렉터리는 구분자로 분리
String[] directories = directory.split(separator);
f.directories = directories;
// 파일명은 이름과 확장자로 분리
Matcher m2 = fileNamePattern.matcher(fileName);
if (m2.matches()) {
f.name = m2.group("name");
f.extension = m2.group("ext").substring(1);
} else {
f.name = fileName;
}
}
return f;
}).collect(Collectors.toList());
// 출력
result.forEach(System.out::println);
}
}
@Test
public void ex13() throws IOException {
Employee source = new Employee("antop", 5000);
System.out.println(source); // ch09.Employee@694f9431 {name='antop', salary=5000.0}
try (ByteArrayOutputStream bas = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bas);) {
oos.writeObject(source); // write
try (ByteArrayInputStream bai = new ByteArrayInputStream(bas.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bai);) {
try {
Employee target = (Employee) ois.readObject(); // read
System.out.println(target); // ch09.Employee@4aa8f0b4 {name='antop', salary=5000.0}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
// 14. 인스턴스 변수로 x와 y가 포함된 직렬화 기능한 클래스 Point를 구현하라. Point 객체의 배열을 파일로 직렬화하는 프로그램과 해당 파일을 읽는 프로그램을 작성하라.
@Test
public void ex14() throws Exception {
// create point object
int size = 5;
Random random = new Random();
Point[] points = new Point[size];
for (int i = 0; i < size; i++) {
points[i] = new Point(random.nextInt(10), random.nextInt(10));
}
System.out.println("points = " + Arrays.toString(points));
// points = [ch09.Point@f2a0b8e {x=0, y=6}, ch09.Point@593634ad {x=5, y=4}, ch09.Point@20fa23c1 {x=2, y=8}, ch09.Point@3581c5f3 {x=4, y=5}, ch09.Point@6aa8ceb6 {x=8, y=4}]
// save to file
PointDisk.save(Paths.get("D:\\points.txt"), points);
// load from file
Point[] loaded = PointDisk.load(Paths.get("D:\\\\points.txt"));
System.out.println("points = " + Arrays.toString(loaded));
// points = [ch09.Point@2c13da15 {x=0, y=6}, ch09.Point@77556fd {x=5, y=4}, ch09.Point@368239c8 {x=2, y=8}, ch09.Point@9e89d68 {x=4, y=5}, ch09.Point@3b192d32 {x=8, y=4}]
}
}