Java tutorial
/** * The contents of this file are subject to the license and copyright * detailed in the LICENSE file at the root of the source * tree and available online at * * https://github.com/keeps/roda */ package org.roda.core.util; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.file.Path; import java.security.DigestInputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.commons.io.IOUtils; import org.roda.core.data.common.RodaConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Rui Castro * @author Hlder Silva <hsilva@keep.pt> * */ public class FileUtility { private static final Logger LOGGER = LoggerFactory.getLogger(FileUtility.class); private FileUtility() { // do nothing } public static InputStream getConfigurationFile(Path configPath, String relativePath) { InputStream ret; Path staticConfig = configPath.resolve(relativePath); if (staticConfig.toFile().exists()) { try { ret = new FileInputStream(staticConfig.toFile()); LOGGER.debug("Using static configuration"); } catch (FileNotFoundException e) { LOGGER.debug("Couldn't find static configuration file - {}", staticConfig); LOGGER.debug("Using internal configuration"); ret = FileUtility.class .getResourceAsStream("/" + RodaConstants.CORE_CONFIG_FOLDER + "/" + relativePath); } } else { LOGGER.debug("Using internal configuration"); ret = FileUtility.class .getResourceAsStream("/" + RodaConstants.CORE_CONFIG_FOLDER + "/" + relativePath); } return ret; } /** * * @param is * @param digestAlgorithm * @return a {@link java.lang.String} with calculated checksum in hexadecimal. * @throws NoSuchAlgorithmException * @throws IOException */ public static String checksum(InputStream is, String digestAlgorithm) throws NoSuchAlgorithmException, IOException { return byteArrayToHexString(digest(is, digestAlgorithm)); } /** * * @param is * @param digestAlgorithm * @return a byte array with the calculated digest. * @throws NoSuchAlgorithmException * @throws IOException */ private static byte[] digest(InputStream is, String digestAlgorithm) throws NoSuchAlgorithmException, IOException { MessageDigest digestor = MessageDigest.getInstance(digestAlgorithm); // reads file in 1Mbyte chunks (1048576 bytes - 2^20 bytes) int bufSize = 1048576; // 1 MByte byte[] buffer = new byte[bufSize]; int n = is.read(buffer, 0, bufSize); while (n != -1) { digestor.update(buffer, 0, n); n = is.read(buffer, 0, bufSize); } is.close(); return digestor.digest(); } public static Map<String, String> checksums(InputStream is, Collection<String> algorithms) throws NoSuchAlgorithmException, IOException { Map<String, String> ret = new HashMap<>(); Map<String, MessageDigest> digestors = new HashMap<>(); for (String algorithm : algorithms) { digestors.put(algorithm, MessageDigest.getInstance(algorithm)); } // reads file in 1Mbyte chunks (1048576 bytes - 2^20 bytes) int bufSize = 1048576; // 1 MByte byte[] buffer = new byte[bufSize]; int n = is.read(buffer, 0, bufSize); while (n != -1) { for (MessageDigest digestor : digestors.values()) { digestor.update(buffer, 0, n); } n = is.read(buffer, 0, bufSize); } for (Entry<String, MessageDigest> entry : digestors.entrySet()) { ret.put(entry.getKey(), byteArrayToHexString(entry.getValue().digest())); } IOUtils.closeQuietly(is); return ret; } public static Map<String, String> copyAndChecksums(InputStream in, OutputStream out, Collection<String> algorithms) throws NoSuchAlgorithmException, IOException { Map<String, String> ret = new HashMap<>(); Map<String, DigestInputStream> streams = new HashMap<>(); InputStream stream = in; for (String algorithm : algorithms) { stream = new DigestInputStream(stream, MessageDigest.getInstance(algorithm)); streams.put(algorithm, (DigestInputStream) stream); } IOUtils.copyLarge(stream, out); for (Entry<String, DigestInputStream> entry : streams.entrySet()) { ret.put(entry.getKey(), byteArrayToHexString(entry.getValue().getMessageDigest().digest())); } return ret; } /** * Convert a byte[] array to readable string format. This makes the "hex" * readable! * * @return result String buffer in String format * @param in * byte[] buffer to convert to string format */ private static String byteArrayToHexString(byte in[]) { byte ch = 0x00; int i = 0; if (in == null || in.length <= 0) { return null; } String[] pseudo = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" }; StringBuilder out = new StringBuilder(in.length * 2); while (i < in.length) { ch = (byte) (in[i] & 0xF0); // Strip off high nibble ch = (byte) (ch >>> 4); // shift the bits down ch = (byte) (ch & 0x0F); // must do this is high order bit is on! out.append(pseudo[ch]); // convert the nibble to a String // Character ch = (byte) (in[i] & 0x0F); // Strip off low nibble out.append(pseudo[ch]); // convert the nibble to a String // Character i++; } return new String(out); } /** * Returns a list with all the files inside a given directory. * * @param dir * the directory to list the contents. * @return a list with all the files and directories. */ public static List<File> listFilesRecursively(File dir) { ArrayList<File> files = new ArrayList<>(); File[] list = dir.listFiles(); for (int i = 0; i < list.length; i++) { if (list[i].isDirectory()) { files.addAll(listFilesRecursively(list[i])); } else { files.add(list[i]); } } return files; } /** * Gets file extension from filename * * @param filename * @return file extension if filename has at least one dot ; otherwise an * empty string */ public static String getFileNameExtension(String filename) { String res = ""; int lastIndexOf = filename.lastIndexOf('.'); if (lastIndexOf != -1) { res = filename.substring(lastIndexOf + 1); } return res; } }