// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.io; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.UncheckedIOException; import java.io.Writer; import java.nio.channels.FileChannel; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.NoSuchFileException; import java.util.List; import java.nio.charset.Charset; import java.nio.ByteBuffer; /** * Some static io convenience methods. * * @author bratseth * @author Bjorn Borud */ public abstract class IOUtils { static private final Charset utf8Charset = StandardCharsets.UTF_8; /** Closes a writer, or does nothing if the writer is null */ public static void closeWriter(Writer writer) { if (writer == null) return; try { writer.close(); } catch (IOException e) {} } /** Closes a reader, or does nothing if the reader is null */ public static void closeReader(Reader reader) { if (reader == null) return; try { reader.close(); } catch (IOException e) {} } /** Closes an input stream, or does nothing if the stream is null */ public static void closeInputStream(InputStream stream) { if (stream == null) return; try { stream.close(); } catch (IOException e) {} } /** Closes an output stream, or does nothing if the stream is null */ public static void closeOutputStream(OutputStream stream) { if (stream == null) return; try { stream.close(); } catch (IOException e) {} } /** * Creates a buffered reader * * @param filename the name or path of the file * @param encoding the encoding of the file, for instance "UTF-8" */ public static BufferedReader createReader(File filename, String encoding) throws IOException { return new BufferedReader(new InputStreamReader(new FileInputStream(filename), encoding)); } /** * Creates a buffered reader * * @param filename the name or path of the file * @param encoding the encoding of the file, for instance "UTF-8" */ public static BufferedReader createReader(String filename, String encoding) throws IOException { return new BufferedReader(new InputStreamReader(new FileInputStream(filename), encoding)); } /** Creates a buffered reader in the default encoding */ public static BufferedReader createReader(String filename) throws IOException { return new BufferedReader(new FileReader(filename)); } /** * Creates a buffered writer, * and the directories to contain it if they do not exist * * @param filename the name or path of the file * @param encoding the encoding to use, for instance "UTF-8" * @param append whether to append to the files if it exists */ public static BufferedWriter createWriter(String filename, String encoding, boolean append) throws IOException { createDirectory(filename); return new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename, append), encoding)); } /** * Creates a buffered writer, * and the directories to contain it if they do not exist * * @param file the file to write to * @param encoding the encoding to use, for instance "UTF-8" * @param append whether to append to the files if it exists */ public static BufferedWriter createWriter(File file, String encoding, boolean append) throws IOException { createDirectory(file.getAbsolutePath()); return new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, append),encoding)); } /** * Creates a buffered writer in the default encoding * * @param filename the name or path of the file * @param append whether to append to the files if it exists */ public static BufferedWriter createWriter(String filename, boolean append) throws IOException { createDirectory(filename); return new BufferedWriter(new FileWriter(filename, append)); } /** * Creates a buffered writer in the default encoding * * @param file the file to write to * @param append whether to append to the files if it exists */ public static BufferedWriter createWriter(File file, boolean append) throws IOException { createDirectory(file.getAbsolutePath()); return new BufferedWriter(new FileWriter(file, append)); } /** Creates the directory path of this file if it does not exist */ public static void createDirectory(String filename) { File directory = new File(filename).getParentFile(); if (directory != null) directory.mkdirs(); } /** * Copies the n first lines of a file to another file. * If the out file exists it will be overwritten * * @throws IOException if copying fails */ public static void copy(String inFile, String outFile, int lineCount) throws IOException { BufferedReader reader = null; BufferedWriter writer = null; try { reader = createReader(inFile); writer = createWriter(outFile, false); int c; int newLines = 0; while (-1 != (c=reader.read()) && newLines 0) { out.write(buf, 0, len); } } finally { closeInputStream(in); closeOutputStream(out); } } else if (maxRecurseLevel!=0) { // copy directory if allowed if (!targetLocation.exists()) targetLocation.mkdirs(); String[] children = sourceLocation.list(filter); for (int i=0; i getLines(String fileName) throws IOException { BufferedReader reader = null; try { List lines = new java.util.ArrayList<>(); reader = createReader(fileName,"utf8"); String line; while (null != (line = reader.readLine())) lines.add(line); return lines; } finally { closeReader(reader); } } /** * Recursive deletion of directories */ public static boolean recursiveDeleteDir(File dir) { if (dir.isDirectory()) { String[] children = dir.list(); for (String child : children) { boolean success = recursiveDeleteDir(new File(dir, child)); if (!success) return false; } } // The directory is now empty so delete it return dir.delete(); } /** * Encodes string as UTF-8 into ByteBuffer */ public static ByteBuffer utf8ByteBuffer(String s) { return utf8Charset.encode(s); } /** * Reads the contents of a UTF-8 text file into a String. * * @param file the file to read, or null * @return the file content as a string, or null if the input file was null */ public static String readFile(File file) throws IOException { try { if (file == null) return null; return Files.readString(file.toPath(), utf8Charset); } catch (NoSuchFileException e) { throw new NoSuchFileException("Could not find file '" + file.getAbsolutePath() + "'"); } } /** * Reads all the content of the given input stream, in chunks of at max chunkSize */ public static byte[] readBytes(InputStream stream, int chunkSize) throws IOException { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); int nRead; byte[] data = new byte[chunkSize]; while ((nRead = stream.read(data, 0, data.length)) != -1) buffer.write(data, 0, nRead); buffer.flush(); return buffer.toByteArray(); } /** * Reads the content of a file into a byte array */ public static byte[] readFileBytes(File file) throws IOException { long lengthL = file.length(); if (lengthL>Integer.MAX_VALUE) throw new IllegalArgumentException("File too big for byte array: "+file.getCanonicalPath()); try (InputStream in = new FileInputStream(file)) { int length = (int)lengthL; byte[] array = new byte[length]; int offset = 0; int count=0; while (offset < length && (count = in.read(array, offset, (length - offset)))>=0) offset += count; return array; } } /** * Reads all data from a reader into a string. Uses a buffer to speed up reading. */ public static String readAll(Reader reader) throws IOException { StringBuilder sb = new StringBuilder(); try (BufferedReader buffered = new BufferedReader(reader)) { int c; while ((c = buffered.read()) != -1) sb.appendCodePoint(c); } return sb.toString(); } /** Read an input stream completely into a string */ public static String readAll(InputStream stream, Charset charset) throws IOException { return new String(stream.readAllBytes(), charset); } /** Convenience method for closing a list of readers. Does nothing if the given reader list is null. */ public static void closeAll(List readers) { if (readers==null) return; for (Reader reader : readers) closeReader(reader); } /** * Writes the given string to the file */ public static void writeFile(File file, String text, boolean append) throws IOException { BufferedWriter out = null; try { out = createWriter(file, append); out.write(text); } finally { closeWriter(out); } } /** Writes the given content to the file (replacing any existing content) */ public static void writeFile(File file, byte[] content) throws UncheckedIOException { try (FileOutputStream out = new FileOutputStream(file)) { out.write(content); } catch (IOException e) { throw new UncheckedIOException(e); } } /** * Writes the given string to the file */ public static void writeFile(String file, String text, boolean append) throws IOException { writeFile(new File(file), text, append); } }