/* * Copyright (c) 2014 tabletoptool.com team. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html * * Contributors: * rptools.com team - initial implementation * tabletoptool.com team - further development */ package com.t3.persistence; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.Reader; import java.io.StringWriter; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.util.Calendar; import java.util.Date; import java.util.Enumeration; import java.util.GregorianCalendar; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; import org.apache.commons.io.IOUtils; import org.apache.log4j.Logger; public class FileUtil { private static final Logger log = Logger.getLogger(FileUtil.class); public static byte[] loadFile(File file) throws IOException { try(InputStream is=new FileInputStream(file);){ return IOUtils.toByteArray(is); } } public static byte[] loadResource(String resource) throws IOException { try (InputStream is = FileUtil.class.getClassLoader().getResourceAsStream(resource)){ return getBytes(is); } } public static List<String> getLines(File file) throws IOException { List<String> list; try (FileReader reader=new FileReader(file)) { list = IOUtils.readLines(reader); } return list; } public static void saveResource(String resource, File destDir) throws IOException { int index = resource.lastIndexOf('/'); String filename = index >= 0 ? resource.substring(index + 1) : resource; saveResource(resource, destDir, filename); } public static void saveResource(String resource, File destDir, String filename) throws IOException { File outFilename = new File(destDir + File.separator + filename); try ( InputStream inStream = FileUtil.class.getClassLoader().getResourceAsStream(resource); BufferedOutputStream outStream = new BufferedOutputStream(new FileOutputStream(outFilename)); ){ IOUtils.copy(inStream, outStream); } } private static final Pattern TRIM_EXTENSION_PATTERN = Pattern.compile("^(.*)\\.([^\\.]*)$"); public static String getNameWithoutExtension(File file) { return getNameWithoutExtension(file.getName()); } public static String getNameWithoutExtension(String filename) { if (filename == null) { return null; } Matcher matcher = TRIM_EXTENSION_PATTERN.matcher(filename); if (!matcher.find()) { return filename; } return matcher.group(1); } public static String getNameWithoutExtension(URL url) { return getNameWithoutExtension(new File(url.getFile())); } private static byte[] getBytes(InputStream inStream) throws IOException { if (inStream == null) throw new IllegalArgumentException("InputStream cannot be null"); byte[] result = IOUtils.toByteArray(inStream); return result; } public static byte[] getBytes(URL url) throws IOException { try(InputStream is = url.openStream()){ return getBytes(is); } } public static byte[] getBytes(File file) throws IOException { return getBytes(file.toURI().toURL()); } /** * Returns the data in a file using the UTF-8 character encoding. The platform * default may not be appropriate since the file could've been produced on a * different platform. The only safe thing to do is use UTF-8 and hope that * everyone uses it by default when they edit text files. :-/ */ public static String getString(InputStream is) throws IOException { if (is == null) throw new IllegalArgumentException("InputStream cannot be null"); String result = IOUtils.toString(is, "UTF-8"); return result; } /** * Reads the given file and returns the contents as a UTF-8 encoded string. * See {@link #getString(InputStream)} for additional details. * * @param file file to retrieve contents from * @return String representing the contents * @throws IOException */ public static String getString(File file) throws IOException { try (InputStream is = new FileInputStream(file)){ return getString(is); } } /** * Given an InputStream this method tries to figure out what the content type might be. * @param in the InputStream to check * @return a <code>String</code> representing the content type name */ public static String getContentType(InputStream in) { String type = ""; try { type = URLConnection.guessContentTypeFromStream(in); if (log.isDebugEnabled()) log.debug("result from guessContentTypeFromStream() is " + type); } catch (IOException e) { } return type; } /** * Given a URL this method tries to figure out what the content type might be based * only on the filename extension. * * @param url the URL to check * @return a <code>String</code> representing the content type name */ public static String getContentType(URL url) { String type = ""; type = URLConnection.guessContentTypeFromName(url.getPath()); if (log.isDebugEnabled()) log.debug("result from guessContentTypeFromName(" + url.getPath() + ") is " + type); return type; } /** * Given a URL this method tries to figure out what the content type might be based * only on the filename extension. * * @param url the URL to check * @return a <code>String</code> representing the content type name */ public static String getContentType(File file) { try { return getContentType(file.toURI().toURL()); } catch (MalformedURLException e) { return null; } } /** * Returns a Reader from the given <code>File</code> object. * * @param file the input data source * @return a String representing the data * @throws IOException */ public static Reader getFileAsReader(File file) throws IOException { return getURLAsReader(file.toURI().toURL()); } /** * Given a URL this method determines the content type of the URL (if possible) and * then returns a Reader with the appropriate character encoding. * * @param url the source of the data stream * @return String representing the data * @throws IOException */ public static Reader getURLAsReader(URL url) throws IOException { InputStreamReader isr = null; URLConnection conn = null; String encoding = "UTF-8"; // We're assuming character here, but it could be bytes. Perhaps we should // check the MIME type returned by the network server? conn = url.openConnection(); if (log.isDebugEnabled()) { String type = URLConnection.guessContentTypeFromName(url.getPath()); log.debug("result from guessContentTypeFromName(" + url.getPath() + ") is " + type); type = getContentType(conn.getInputStream()); // Now make a guess and change 'encoding' to match the content type... } isr = new InputStreamReader(conn.getInputStream(), encoding); return isr; } public static InputStream getFileAsInputStream(File file) throws IOException { return getURLAsInputStream(file.toURI().toURL()); } /** * Given a URL this method determines the content type of the URL (if possible) and * then returns a Reader with the appropriate character encoding. * * @param url the source of the data stream * @return String representing the data * @throws IOException */ public static InputStream getURLAsInputStream(URL url) throws IOException { InputStream is = null; URLConnection conn = null; // We're assuming character here, but it could be bytes. Perhaps we should // check the MIME type returned by the network server? conn = url.openConnection(); if (log.isDebugEnabled()) { String type = URLConnection.guessContentTypeFromName(url.getPath()); log.debug("result from guessContentTypeFromName(" + url.getPath() + ") is " + type); type = getContentType(conn.getInputStream()); log.debug("result from getContentType(" + url.getPath() + ") is " + type); } is = conn.getInputStream(); return is; } /** * Because this method takes a <code>Reader</code> it can be locale-correct by * creating a FileReader (for example) that uses UTF-8 or some other charset. * * @param r the <code>Reader</code> to obtain textual data from * @return an array of <code>char</code> * @throws IOException */ private static String getChars(Reader r) throws IOException { if (r == null) { throw new IllegalArgumentException("Reader cannot be null"); } try(StringWriter sw = new StringWriter(10 * 1024)) { char[] c = new char[4096]; while (true) { int read = r.read(c); if (read == -1) { break; } sw.write(c, 0, read); } return sw.toString(); } } public static void writeBytes(File file, byte[] data) throws IOException { // Ensure path exists if (file.exists()) file.delete(); else file.getParentFile().mkdirs(); try (OutputStream os = new FileOutputStream(file)){ IOUtils.write(data, os); } } public static void copyFile(File sourceFile, File destFile) throws IOException { try ( InputStream is = new FileInputStream(sourceFile); OutputStream os = new FileOutputStream(destFile); ){ IOUtils.copy(is, os); } } public static void unzip(String classpathFile, File destDir) throws IOException { try { unzip(FileUtil.class.getClassLoader().getResource(classpathFile), destDir); } catch (Exception e) { throw new IOException(e); } } public static void unzip(URL url, File destDir) throws IOException { if (url == null) throw new IOException ("URL cannot be null"); try(ZipInputStream zis = new ZipInputStream(new BufferedInputStream(url.openStream()))){ unzip(zis, destDir); } } public static void unzip(ZipInputStream in, File destDir) throws IOException { if (in == null) throw new IOException("input stream cannot be null"); // Prepare destination destDir.mkdirs(); String absDestDir = destDir.getAbsolutePath() + File.separator; // Pull out the files ZipEntry entry = null; while ((entry = in.getNextEntry()) != null) { if (entry.isDirectory()) continue; // Prepare file destination String path = absDestDir + entry.getName(); File file = new File(path); file.getParentFile().mkdirs(); try(OutputStream out = new FileOutputStream(file)) { IOUtils.copy(in, out); } in.closeEntry(); } } public static void unzipFile(File sourceFile, File destDir) throws IOException { if (!sourceFile.exists()) throw new IOException("source file does not exist: " + sourceFile); try (ZipFile zipFile = new ZipFile(sourceFile)){ Enumeration<? extends ZipEntry> entries = zipFile.entries(); while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); if (entry.isDirectory()) continue; String path = destDir.getAbsolutePath() + File.separator + entry.getName(); File file = new File(path); file.getParentFile().mkdirs(); //System.out.println("Writing file: " + path); try( InputStream is = zipFile.getInputStream(entry); BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(path)); ) { IOUtils.copy(is, os); } } } } public static void delete(File file, int daysOld) throws IOException { Calendar olderThan = new GregorianCalendar(); olderThan.add(Calendar.DATE, -daysOld); boolean shouldDelete = new Date(file.lastModified()).before(olderThan.getTime()); if (file.isDirectory()) { // Wipe the contents first for (File currfile : file.listFiles()) { if (".".equals(currfile.getName()) || "..".equals(currfile.getName())) continue; delete(currfile, daysOld); } } if (shouldDelete) file.delete(); } public static void delete(File file) { if (file.isDirectory()) { // Wipe the contents first for (File currfile : file.listFiles()) { if (".".equals(currfile.getName()) || "..".equals(currfile.getName())) continue; delete(currfile); } } file.delete(); } public static Object objFromResource(Class<?> loadingClass, String name) { try (InputStream is=loadingClass.getResourceAsStream(name)) { return Persister.newInstance().fromXML(is); } catch (IOException e) { throw new Error(e); } } }