/* ************************************************************************ # # DivConq # # http://divconq.com/ # # Copyright: # Copyright 2014 eTimeline, LLC. All rights reserved. # # License: # See the license.txt file in the project's top-level directory for details. # # Authors: # * Andy White # ************************************************************************ */ package divconq.util; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.Closeable; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream; import divconq.io.LineIterator; import divconq.lang.Memory; import divconq.lang.chars.Utf8Encoder; import divconq.lang.op.FuncResult; import divconq.lang.op.OperationResult; public class IOUtil { /** * Read entire text file into a string. * * @param file to read * @return file content if readable, otherwise null */ public static String readEntireFile(File file) { // TODO improve to funcresult - update to nio2 BufferedReader br = null; try { StringBuilder sb = new StringBuilder(); br = new BufferedReader(new FileReader(file)); String line = br.readLine(); while (line != null) { sb.append(line); sb.append("\n"); line = br.readLine(); } return sb.toString(); } catch (IOException x) { } finally { closeQuietly(br); } return null; } /** * Read entire text file into a string. * * @param file to read * @return file content if readable, otherwise null */ public static FuncResult<CharSequence> readEntireFile(Path file) { FuncResult<CharSequence> res = new FuncResult<>(); BufferedReader br = null; try { StringBuilder sb = new StringBuilder(); br = Files.newBufferedReader(file, Charset.forName("UTF-8")); String line = br.readLine(); while (line != null) { sb.append(line); sb.append("\n"); line = br.readLine(); } res.setResult(sb); } catch (IOException x) { res.error("Unabled to read file " + file + ", error: " + x); } finally { closeQuietly(br); } return res; } /** * Read entire sream into a string. * * @param stream to read * @return stream content if readable, otherwise null */ public static String readEntireStream(InputStream stream) { // TODO improve to funcresult - update to nio2 BufferedReader br = null; try { StringBuilder sb = new StringBuilder(); br = new BufferedReader(new InputStreamReader(stream)); String line = br.readLine(); while (line != null) { sb.append(line); sb.append("\n"); line = br.readLine(); } return sb.toString(); } catch (IOException x) { } finally { closeQuietly(br); } return null; } public static OperationResult saveEntireFile(Path dest, String content) { OperationResult or = new OperationResult(); try { Files.createDirectories(dest.getParent()); Files.write(dest, Utf8Encoder.encode(content), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE, StandardOpenOption.SYNC); } catch (Exception x) { or.error(1, "Error saving file contents: " + x); } return or; } public static boolean saveEntireFile2(Path dest, String content) { try { Files.createDirectories(dest.getParent()); Files.write(dest, Utf8Encoder.encode(content), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE, StandardOpenOption.SYNC); } catch (Exception x) { return false; } return true; } public static boolean saveEntireFile2(Path dest, Memory content) { try { Files.createDirectories(dest.getParent()); Files.write(dest, content.toArray(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE, StandardOpenOption.SYNC); } catch (Exception x) { return false; } return true; } /* public static File safeSave(InputStream in, String dest) { File f = new File(dest); f.getParentFile().mkdirs(); // TODO check FileOutputStream fos = null; try { fos = new FileOutputStream(f); IOUtils.copy(in, fos); } catch (Exception x) { // TODO } finally { IOUtils.closeQuietly(fos); IOUtils.closeQuietly(in); } return f; } */ public static byte[] charsEncodeAndCompress(CharSequence v) { try { byte[] buffer = Utf8Encoder.encode(v); ByteArrayOutputStream bos = new ByteArrayOutputStream(); GzipCompressorOutputStream cos = new GzipCompressorOutputStream(bos); cos.write(buffer); cos.close(); bos.close(); return bos.toByteArray(); } catch (Exception x) { } return null; } // TODO improve to funcresult public static Memory readEntireFileToMemory(File file) { return IOUtil.readEntireFileToMemory(file.toPath()); } // TODO improve to funcresult public static Memory readEntireFileToMemory(Path file) { try (FileChannel ch = FileChannel.open(file, StandardOpenOption.READ)) { Memory mem = new Memory(); // TODO improve mem to read right from channel... ByteBuffer bb = ByteBuffer.allocate(4096); int amt = ch.read(bb); while (amt != -1) { bb.flip(); mem.write(bb); bb.clear(); amt = ch.read(bb); } mem.setPosition(0); return mem; } catch (IOException x) { } return null; } static public boolean isLegalFilename(String name) { if (StringUtil.isEmpty(name)) return false; if (name.equals(".") || name.contains("..") || name.contains("*") || name.contains("\"") || name.contains("/") || name.contains("\\") || name.contains("<") || name.contains(">") || name.contains(":") || name.contains("?") || name.contains("|")) return false; return true; } public static void closeQuietly(Closeable... closeables) { if (closeables == null) return; for (Closeable closeable : closeables) { try { if (closeable != null) closeable.close(); } catch (IOException x) { // ignore } } } /** * Returns an Iterator for the lines in an <code>InputStream</code>, using * the character encoding specified (or default encoding if null). * <p> * <code>LineIterator</code> holds a reference to the open * <code>InputStream</code> specified here. When you have finished with * the iterator you should close the stream to free internal resources. * This can be done by closing the stream directly, or by calling * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}. * <p> * The recommended usage pattern is: * <pre> * try { * LineIterator it = IOUtils.lineIterator(stream, charset); * while (it.hasNext()) { * String line = it.nextLine(); * /// do something with line * } * } finally { * IOUtils.closeQuietly(stream); * } * </pre> * * @param input the <code>InputStream</code> to read from, not null * @param encoding the encoding to use, null means platform default * @return an Iterator of the lines in the reader, never null * @throws IllegalArgumentException if the input is null * @throws IOException if an I/O error occurs, such as if the encoding is invalid * @since 2.3 */ public static LineIterator lineIterator(InputStream input, Charset encoding) throws IOException { return new LineIterator(new InputStreamReader(input, encoding)); } public static long byteArrayToLong(byte[] b) { return (b[0] & 0xff) << 56 | (b[1] & 0xff) << 48 | (b[2] & 0xff) << 40 | (b[3] & 0xff) << 32 | (b[4] & 0xff) << 24 | (b[5] & 0xff) << 16 | (b[6] & 0xff) << 8 | (b[7] & 0xff); } public static byte[] longToByteArray(long a) { byte[] ret = new byte[8]; ret[0] = (byte) ((a >> 56) & 0xff); ret[1] = (byte) ((a >> 48) & 0xff); ret[2] = (byte) ((a >> 40) & 0xff); ret[3] = (byte) ((a >> 32) & 0xff); ret[4] = (byte) ((a >> 24) & 0xff); ret[5] = (byte) ((a >> 16) & 0xff); ret[6] = (byte) ((a >> 8) & 0xff); ret[7] = (byte) (a & 0xff); return ret; } public static int byteArrayToInt(byte[] b) { return (b[0] & 0xff) << 24 | (b[1] & 0xff) << 16 | (b[2] & 0xff) << 8 | (b[3] & 0xff); } public static byte[] intToByteArray(int a) { byte[] ret = new byte[4]; ret[0] = (byte) ((a >> 24) & 0xff); ret[1] = (byte) ((a >> 16) & 0xff); ret[2] = (byte) ((a >> 8) & 0xff); ret[3] = (byte) (a & 0xff); return ret; } }