1
2
3
4
5 package oshi.util;
6
7 import java.io.BufferedReader;
8 import java.io.ByteArrayOutputStream;
9 import java.io.File;
10 import java.io.IOException;
11 import java.io.InputStream;
12 import java.io.InputStreamReader;
13 import java.io.Reader;
14 import java.net.URL;
15 import java.nio.ByteBuffer;
16 import java.nio.ByteOrder;
17 import java.nio.charset.CharsetDecoder;
18 import java.nio.charset.StandardCharsets;
19 import java.nio.file.Files;
20 import java.nio.file.Path;
21 import java.nio.file.Paths;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.LinkedHashSet;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Properties;
30 import java.util.stream.Collectors;
31 import java.util.stream.Stream;
32
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 import com.sun.jna.Native;
37 import com.sun.jna.NativeLong;
38 import com.sun.jna.Pointer;
39 import com.sun.jna.platform.unix.LibCAPI.size_t;
40
41 import oshi.annotation.concurrent.ThreadSafe;
42
43
44
45
46 @ThreadSafe
47 public final class FileUtil {
48
49 private static final Logger LOG = LoggerFactory.getLogger(FileUtil.class);
50
51 private static final String READING_LOG = "Reading file {}";
52 private static final String READ_LOG = "Read {}";
53
54 private static final int BUFFER_SIZE = 1024;
55
56 private FileUtil() {
57 }
58
59
60
61
62
63
64
65
66
67 public static List<String> readFile(String filename) {
68 return readFile(filename, true);
69 }
70
71
72
73
74
75
76
77
78
79
80 public static List<String> readFile(String filename, boolean reportError) {
81 if (new File(filename).canRead()) {
82 if (LOG.isDebugEnabled()) {
83 LOG.debug(READING_LOG, filename);
84 }
85 try {
86 return Files.readAllLines(Paths.get(filename), StandardCharsets.UTF_8);
87 } catch (IOException e) {
88 if (reportError) {
89 LOG.error("Error reading file {}. {}", filename, e.getMessage());
90 } else {
91 LOG.debug("Error reading file {}. {}", filename, e.getMessage());
92 }
93 }
94 } else if (reportError) {
95 LOG.warn("File not found or not readable: {}", filename);
96 }
97 return Collections.emptyList();
98 }
99
100
101
102
103
104
105
106
107
108
109 public static List<String> readLines(String filename, int count) {
110 return readLines(filename, count, true);
111 }
112
113
114
115
116
117
118
119
120
121
122
123 public static List<String> readLines(String filename, int count, boolean reportError) {
124 Path file = Paths.get(filename);
125 if (Files.isReadable(file)) {
126 if (LOG.isDebugEnabled()) {
127 LOG.debug(READING_LOG, filename);
128 }
129 CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
130 try (Reader isr = new InputStreamReader(Files.newInputStream(file), decoder);
131 BufferedReader reader = new BufferedReader(isr, BUFFER_SIZE)) {
132 List<String> lines = new ArrayList<>(count);
133 for (int i = 0; i < count; ++i) {
134 String line = reader.readLine();
135 if (line == null) {
136 break;
137 }
138 lines.add(line);
139 }
140 return lines;
141 } catch (IOException e) {
142 if (reportError) {
143 LOG.error("Error reading file {}. {}", filename, e.getMessage());
144 } else {
145 LOG.debug("Error reading file {}. {}", filename, e.getMessage());
146 }
147 }
148 } else if (reportError) {
149 LOG.warn("File not found or not readable: {}", filename);
150 }
151 return Collections.emptyList();
152 }
153
154
155
156
157
158
159
160
161
162 public static byte[] readAllBytes(String filename, boolean reportError) {
163 if (new File(filename).canRead()) {
164 if (LOG.isDebugEnabled()) {
165 LOG.debug(READING_LOG, filename);
166 }
167 try {
168 return Files.readAllBytes(Paths.get(filename));
169 } catch (IOException e) {
170 if (reportError) {
171 LOG.error("Error reading file {}. {}", filename, e.getMessage());
172 } else {
173 LOG.debug("Error reading file {}. {}", filename, e.getMessage());
174 }
175 }
176 } else if (reportError) {
177 LOG.warn("File not found or not readable: {}", filename);
178 }
179 return new byte[0];
180 }
181
182
183
184
185
186
187
188
189
190 public static ByteBuffer readAllBytesAsBuffer(String filename) {
191 byte[] bytes = readAllBytes(filename, false);
192 ByteBuffer buff = ByteBuffer.allocate(bytes.length);
193 buff.order(ByteOrder.nativeOrder());
194 for (byte b : bytes) {
195 buff.put(b);
196 }
197 buff.flip();
198 return buff;
199 }
200
201
202
203
204
205
206
207 public static byte readByteFromBuffer(ByteBuffer buff) {
208 if (buff.position() < buff.limit()) {
209 return buff.get();
210 }
211 return 0;
212 }
213
214
215
216
217
218
219
220 public static short readShortFromBuffer(ByteBuffer buff) {
221 if (buff.position() <= buff.limit() - 2) {
222 return buff.getShort();
223 }
224 return 0;
225 }
226
227
228
229
230
231
232
233 public static int readIntFromBuffer(ByteBuffer buff) {
234 if (buff.position() <= buff.limit() - 4) {
235 return buff.getInt();
236 }
237 return 0;
238 }
239
240
241
242
243
244
245
246 public static long readLongFromBuffer(ByteBuffer buff) {
247 if (buff.position() <= buff.limit() - 8) {
248 return buff.getLong();
249 }
250 return 0L;
251 }
252
253
254
255
256
257
258
259 public static NativeLong readNativeLongFromBuffer(ByteBuffer buff) {
260 return new NativeLong(Native.LONG_SIZE == 4 ? readIntFromBuffer(buff) : readLongFromBuffer(buff));
261 }
262
263
264
265
266
267
268
269 public static size_t readSizeTFromBuffer(ByteBuffer buff) {
270 return new size_t(Native.SIZE_T_SIZE == 4 ? readIntFromBuffer(buff) : readLongFromBuffer(buff));
271 }
272
273
274
275
276
277
278
279 public static void readByteArrayFromBuffer(ByteBuffer buff, byte[] array) {
280 if (buff.position() <= buff.limit() - array.length) {
281 buff.get(array);
282 }
283 }
284
285
286
287
288
289
290
291 public static Pointer readPointerFromBuffer(ByteBuffer buff) {
292 if (buff.position() <= buff.limit() - Native.POINTER_SIZE) {
293 return Native.POINTER_SIZE == 4 ? new Pointer(buff.getInt()) : new Pointer(buff.getLong());
294 }
295 return Pointer.NULL;
296 }
297
298
299
300
301
302
303
304 public static long getLongFromFile(String filename) {
305 if (LOG.isDebugEnabled()) {
306 LOG.debug(READING_LOG, filename);
307 }
308 List<String> read = FileUtil.readLines(filename, 1, false);
309 if (!read.isEmpty()) {
310 if (LOG.isTraceEnabled()) {
311 LOG.trace(READ_LOG, read.get(0));
312 }
313 return ParseUtil.parseLongOrDefault(read.get(0), 0L);
314 }
315 return 0L;
316 }
317
318
319
320
321
322
323
324
325 public static long getUnsignedLongFromFile(String filename) {
326 if (LOG.isDebugEnabled()) {
327 LOG.debug(READING_LOG, filename);
328 }
329 List<String> read = FileUtil.readLines(filename, 1, false);
330 if (!read.isEmpty()) {
331 if (LOG.isTraceEnabled()) {
332 LOG.trace(READ_LOG, read.get(0));
333 }
334 return ParseUtil.parseUnsignedLongOrDefault(read.get(0), 0L);
335 }
336 return 0L;
337 }
338
339
340
341
342
343
344
345 public static int getIntFromFile(String filename) {
346 if (LOG.isDebugEnabled()) {
347 LOG.debug(READING_LOG, filename);
348 }
349 try {
350 List<String> read = FileUtil.readLines(filename, 1, false);
351 if (!read.isEmpty()) {
352 if (LOG.isTraceEnabled()) {
353 LOG.trace(READ_LOG, read.get(0));
354 }
355 return ParseUtil.parseIntOrDefault(read.get(0), 0);
356 }
357 } catch (NumberFormatException ex) {
358 LOG.warn("Unable to read value from {}. {}", filename, ex.getMessage());
359 }
360 return 0;
361 }
362
363
364
365
366
367
368
369 public static String getStringFromFile(String filename) {
370 if (LOG.isDebugEnabled()) {
371 LOG.debug(READING_LOG, filename);
372 }
373 List<String> read = FileUtil.readLines(filename, 1, false);
374 if (!read.isEmpty()) {
375 if (LOG.isTraceEnabled()) {
376 LOG.trace(READ_LOG, read.get(0));
377 }
378 return read.get(0);
379 }
380 return "";
381 }
382
383
384
385
386
387
388
389
390
391
392
393 public static Map<String, String> getKeyValueMapFromFile(String filename, String separator) {
394 Map<String, String> map = new HashMap<>();
395 if (LOG.isDebugEnabled()) {
396 LOG.debug(READING_LOG, filename);
397 }
398 List<String> lines = FileUtil.readFile(filename, false);
399 for (String line : lines) {
400 String[] parts = line.split(separator);
401 if (parts.length == 2) {
402 map.put(parts[0], parts[1].trim());
403 }
404 }
405 return map;
406 }
407
408
409
410
411
412
413
414
415 public static Properties readPropertiesFromFilename(String propsFilename) {
416 Properties archProps = new Properties();
417
418
419 for (ClassLoader loader : Stream.of(Thread.currentThread().getContextClassLoader(),
420 ClassLoader.getSystemClassLoader(), FileUtil.class.getClassLoader())
421 .collect(Collectors.toCollection(LinkedHashSet::new))) {
422 if (readPropertiesFromClassLoader(propsFilename, archProps, loader)) {
423 return archProps;
424 }
425 }
426 LOG.warn("Failed to load configuration file from classloader: {}", propsFilename);
427 return archProps;
428 }
429
430 private static boolean readPropertiesFromClassLoader(String propsFilename, Properties archProps,
431 ClassLoader loader) {
432 if (loader == null) {
433 return false;
434 }
435
436 try {
437 List<URL> resources = Collections.list(loader.getResources(propsFilename));
438 if (resources.isEmpty()) {
439 LOG.debug("No {} file found from ClassLoader {}", propsFilename, loader);
440 return false;
441 }
442 if (resources.size() > 1) {
443
444 byte[] propsAsBytes = readFileAsBytes(resources.get(0));
445 for (int i = 1; i < resources.size(); i++) {
446 if (!Arrays.equals(propsAsBytes, readFileAsBytes(resources.get(i)))) {
447 LOG.warn("Configuration conflict: there is more than one {} file on the classpath: {}",
448 propsFilename, resources);
449 break;
450 }
451 }
452 }
453 try (InputStream in = resources.get(0).openStream()) {
454 if (in != null) {
455 archProps.load(in);
456 }
457 }
458 return true;
459 } catch (IOException e) {
460 return false;
461 }
462 }
463
464
465
466
467
468
469
470
471 public static byte[] readFileAsBytes(URL url) throws IOException {
472 try (InputStream in = url.openStream()) {
473 ByteArrayOutputStream buf = new ByteArrayOutputStream();
474 byte[] data = new byte[1024];
475 int bytesRead;
476 while ((bytesRead = in.read(data, 0, data.length)) != -1) {
477 buf.write(data, 0, bytesRead);
478 }
479 buf.flush();
480 return buf.toByteArray();
481 }
482 }
483
484
485
486
487
488
489
490 public static String readSymlinkTarget(File file) {
491 try {
492 return Files.readSymbolicLink(Paths.get(file.getAbsolutePath())).toString();
493 } catch (IOException e) {
494 return null;
495 }
496 }
497 }