21 package org.matsim.core.utils.io;
23 import com.github.luben.zstd.ZstdInputStream;
24 import com.github.luben.zstd.ZstdOutputStream;
25 import net.jpountz.lz4.LZ4FrameInputStream;
26 import net.jpountz.lz4.LZ4FrameOutputStream;
27 import org.apache.commons.compress.compressors.CompressorException;
28 import org.apache.commons.compress.compressors.CompressorStreamFactory;
29 import org.apache.logging.log4j.LogManager;
30 import org.apache.logging.log4j.Logger;
32 import java.io.BufferedInputStream;
33 import java.io.BufferedOutputStream;
34 import java.io.BufferedReader;
35 import java.io.BufferedWriter;
36 import java.io.DataInputStream;
37 import java.io.EOFException;
39 import java.io.FileNotFoundException;
40 import java.io.FileOutputStream;
41 import java.io.IOException;
42 import java.io.InputStream;
43 import java.io.InputStreamReader;
44 import java.io.OutputStream;
45 import java.io.OutputStreamWriter;
46 import java.io.PrintStream;
47 import java.io.UncheckedIOException;
48 import java.net.MalformedURLException;
49 import java.net.URISyntaxException;
51 import java.nio.charset.Charset;
52 import java.nio.charset.StandardCharsets;
53 import java.nio.file.*;
54 import java.nio.file.attribute.BasicFileAttributes;
55 import java.security.GeneralSecurityException;
56 import java.util.Arrays;
57 import java.util.Locale;
59 import java.util.TreeMap;
60 import java.util.zip.GZIPInputStream;
61 import java.util.zip.GZIPOutputStream;
175 zstdCompressionLevel = level;
177 logger.error(
"Invalid ZSTD compression level.");
210 if (filename.startsWith(
"jar:file:") || filename.startsWith(
"file:") || filename.startsWith(
"https:" ) || filename.startsWith(
"http:" )) {
212 return new URL(filename);
216 if (filename.startsWith(
"~" + File.separator)) {
217 filename = System.getProperty(
"user.home") + filename.substring(1);
221 File file =
new File(filename);
224 logger.info(String.format(
"Resolved %s to %s", filename, file));
225 return file.toURI().toURL();
229 for (String postfix : COMPRESSION_EXTENSIONS.keySet()) {
230 file =
new File(filename +
"." + postfix);
233 logger.info(String.format(
"Resolved %s to %s", filename, file));
234 return file.toURI().toURL();
239 URL resource =
IOUtils.class.getClassLoader().getResource(filename);
241 if (resource != null) {
242 logger.info(String.format(
"Resolved %s to %s", filename, resource));
247 for (String postfix : COMPRESSION_EXTENSIONS.keySet()) {
248 resource =
IOUtils.class.getClassLoader().getResource(filename +
"." + postfix);
250 if (resource != null) {
251 logger.info(String.format(
"Resolved %s to %s", filename, resource));
256 throw new FileNotFoundException(filename);
257 }
catch (FileNotFoundException | MalformedURLException e) {
258 throw new UncheckedIOException(e);
269 String[] segments = url.getPath().replace(
".enc",
"").split(
"\\.");
270 String lastExtension = segments[segments.length - 1];
271 return COMPRESSION_EXTENSIONS.get(lastExtension.toLowerCase(Locale.ROOT));
283 InputStream inputStream = url.openStream();
285 if (url.getPath().endsWith(
".enc"))
289 if (compression != null) {
290 switch (compression) {
292 inputStream =
new GZIPInputStream(inputStream);
295 inputStream =
new LZ4FrameInputStream(inputStream);
298 inputStream =
new CompressorStreamFactory().createCompressorInputStream(CompressorStreamFactory.BZIP2, inputStream);
301 inputStream =
new ZstdInputStream(inputStream);
307 }
catch (IOException e) {
308 throw new UncheckedIOException(e);
309 }
catch (CompressorException | GeneralSecurityException e) {
310 throw new UncheckedIOException(
new IOException(e));
321 public static BufferedReader
getBufferedReader(URL url, Charset charset)
throws UncheckedIOException {
323 return new BufferedReader(
new InputStreamReader(inputStream, charset));
344 public static OutputStream
getOutputStream(URL url,
boolean append)
throws UncheckedIOException {
346 if (!url.getProtocol().equals(
"file")) {
347 throw new UncheckedIOException(
new IOException(
"Can only write to file:// protocol URLs"));
350 File file =
new File(url.toURI());
353 if ((compression != null && compression !=
CompressionType.
ZSTD) && append && file.exists()) {
354 throw new UncheckedIOException(
new IOException(
"Cannot append to compressed files."));
357 OutputStream outputStream =
new FileOutputStream(file, append);
359 if (compression != null) {
360 switch (compression) {
362 outputStream =
new GZIPOutputStream(outputStream);
365 outputStream =
new LZ4FrameOutputStream(outputStream);
368 outputStream =
new CompressorStreamFactory().createCompressorOutputStream(CompressorStreamFactory.BZIP2, outputStream);
371 outputStream =
new ZstdOutputStream(outputStream, zstdCompressionLevel);
376 return new BufferedOutputStream(outputStream);
377 }
catch (IOException e) {
378 throw new UncheckedIOException(e);
379 }
catch (CompressorException | URISyntaxException e) {
380 throw new UncheckedIOException(
new IOException(e));
391 throws UncheckedIOException {
393 return new BufferedWriter(
new OutputStreamWriter(outputStream, charset));
424 public static void copyStream(
final InputStream fromStream,
final OutputStream toStream)
425 throws UncheckedIOException {
427 byte[] buffer =
new byte[4096];
430 while ((bytesRead = fromStream.read(buffer)) != -1) {
431 toStream.write(buffer, 0, bytesRead);
433 }
catch (IOException e) {
434 throw new UncheckedIOException(e);
448 Files.walkFileTree(path,
new SimpleFileVisitor<Path>() {
450 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
452 return FileVisitResult.CONTINUE;
456 public FileVisitResult postVisitDirectory(Path dir, IOException exc)
throws IOException {
458 return FileVisitResult.CONTINUE;
461 }
catch (IOException e) {
462 throw new UncheckedIOException(e);
474 public static boolean isEqual(InputStream first, InputStream second)
throws UncheckedIOException {
475 byte[] buf1 =
new byte[64 * 1024];
476 byte[] buf2 =
new byte[64 * 1024];
477 try (first; second) {
478 DataInputStream d2 =
new DataInputStream(second);
480 while ((len = first.read(buf1)) > 0) {
481 d2.readFully(buf2,0, len);
482 if (!Arrays.equals(buf1, 0, len, buf2, 0, len)) {
486 return d2.read() < 0;
487 }
catch(EOFException ioe) {
489 }
catch (IOException e) {
490 throw new UncheckedIOException(e);
501 public static URL
getFileUrl(String filename)
throws UncheckedIOException {
503 return new File(filename).toURI().toURL();
504 }
catch (MalformedURLException e) {
505 throw new UncheckedIOException(e);
517 public static URL
extendUrl(URL context, String extension)
throws UncheckedIOException {
518 if (context == null) {
519 throw new IllegalArgumentException(
"Please use IOUtils.getFileUrl");
523 return new URL(context, extension);
524 }
catch (MalformedURLException e) {
562 public static void copyFile(String inputFilename, String outputFilename)
throws IOException {
563 File fromFile =
new File(inputFilename);
564 File toFile =
new File(outputFilename);
565 Files.copy(fromFile.toPath(), toFile.toPath(), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
static final Charset CHARSET_UTF8
static void deleteDirectoryRecursively(Path path)
static int zstdCompressionLevel
static boolean isEqual(InputStream first, InputStream second)
static BufferedWriter getBufferedWriter(URL url)
static final String NATIVE_NEWLINE
static InputStream getInputStream(URL url)
static BufferedWriter getBufferedWriter(String filename)
static InputStream getDecryptedInput(InputStream is)
static void setZstdCompressionLevel(int level)
static BufferedReader getBufferedReader(URL url, Charset charset)
static URL getFileUrl(String filename)
static final Charset CHARSET_WINDOWS_ISO88591
static void copyStream(final InputStream fromStream, final OutputStream toStream)
static BufferedWriter getBufferedWriter(URL url, Charset charset, boolean append)
static final Map< String, CompressionType > COMPRESSION_EXTENSIONS
static OutputStream getOutputStream(URL url, boolean append)
static BufferedReader getBufferedReader(String filename)
static final Logger logger
static void copyFile(String inputFilename, String outputFilename)
static URL resolveFileOrResource(String filename)
static BufferedWriter getAppendingBufferedWriter(String filename)
static URL extendUrl(URL context, String extension)
static PrintStream getPrintStream(URL url)
static CompressionType getCompression(URL url)
static BufferedReader getBufferedReader(URL url)