/* * Autopsy Forensic Browser * * Copyright 2012-2016 Basis Technology Corp. * Contact: carrier <at> sleuthkit <dot> org * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.sleuthkit.autopsy.coreutils; import java.io.File; import java.io.IOException; import java.util.logging.Level; import org.openide.filesystems.FileObject; import java.nio.file.Files; import java.nio.file.Path; /** * File and dir utilities */ public class FileUtil { private static final Logger logger = Logger.getLogger(FileUtil.class.getName()); private static final String TEMP_FILE_NAME = "Autopsy"; //NON-NLS private static final String TEMP_FILE_EXT = null; //NON-NLS /** * Recursively delete all of the files and sub-directories in a directory. * Use deleteFileDir() if you are not sure if the path is a file or * directory. * * @param dirPath Path of the directory to delete * * @return true if the dir was deleted with no errors. False otherwise * (including if the passed in path was for a file). */ public static boolean deleteDir(File dirPath) { if (dirPath.isDirectory() == false || dirPath.exists() == false) { logger.log(Level.WARNING, "deleteDir passed in a non-directory: {0}", dirPath.getPath()); //NON-NLS return false; } File[] files = dirPath.listFiles(); boolean hadErrors = false; if (files != null) { for (File file : files) { if (file.isDirectory()) { if (deleteDir(file) == false) { // message was already logged hadErrors = true; } } else { if (file.delete() == false) { logger.log(Level.WARNING, "Failed to delete file {0}", file.getPath()); //NON-NLS hadErrors = true; } } } } if (dirPath.delete() == false) { logger.log(Level.WARNING, "Failed to delete the empty directory at {0}", dirPath.getPath()); //NON-NLS hadErrors = true; } return !hadErrors; } /** * Delete the file or dir at the given path. If the path is for a directory, * recursively delete its contents. * * @param path the path to the file or directory to delete * * @return true if the file or directory were deleted with no errors. False * otherwise. */ public static boolean deleteFileDir(File path) { boolean sucess = true; if (path.isFile()) { // If it's a file if (!path.delete()) { sucess = false; logger.log(Level.WARNING, "Failed to delete file {0}", path.getPath()); //NON-NLS } } else { // If it's a directory sucess = deleteDir(path); } return sucess; } /** * Copy a file to a new directory, potentially new file name, and overwrite * old one if requested * * @param source source file path * @param destFolder destination folder path * @param newName file name of the copied file, which can be different * from original * @param ext file extension, e.g. ".java" * @param overwrite if new file, already exists, overwrite it (delete it * first) * * @return path to the created file, or null if file was not created * * @throws IOException exception thrown if file copying failed */ public static String copyFile(String source, String destFolder, String newName, String ext, boolean overwrite) throws IOException { final String destFileName = destFolder + File.separator + newName + ext; final File destFile = new File(destFileName); if (destFile.exists()) { if (overwrite) { destFile.delete(); } else { return null; } } final FileObject sourceFileObj = org.openide.filesystems.FileUtil.createData(new File(source)); final FileObject destFolderObj = org.openide.filesystems.FileUtil.createData(new File(destFolder)); // org.openide.filesystems.FileUtil.copyFile requires an extension without the "." e.g. "java" FileObject created = org.openide.filesystems.FileUtil.copyFile(sourceFileObj, destFolderObj, newName, ext.substring(1)); return created.getPath(); } /** * Copy a folder into a new directory. * * @param source path to the source folder * @param path destination path of the new folder * @param folderName name of the new folder * * @return path to the new folder if created, null if it was not created * * @throws IOException exception thrown if file copying failed */ public static String copyFolder(String source, String path, String folderName) throws IOException { String destFolder = path + File.separator + folderName; org.openide.filesystems.FileUtil.createFolder(new File(destFolder)); final FileObject sourceFileObj = org.openide.filesystems.FileUtil.createData(new File(source)); final FileObject destFolderObj = org.openide.filesystems.FileUtil.createData(new File(destFolder)); FileObject created = org.openide.filesystems.FileUtil.copyFile(sourceFileObj, destFolderObj, sourceFileObj.getName(), sourceFileObj.getExt()); return created.getPath(); } /** * Escape special characters in a file name or a file name component * * @param fileName to escape * * @return escaped string */ public static String escapeFileName(String fileName) { //for now escaping /:"*?<>| (not valid in file name, at least on Windows) //with underscores. We are only keeping \ as it could be part of the path. return fileName.replaceAll("[/:\"*?<>|]+", "_"); } /** * Test if the current user has read and write access to the dirPath. * * @param dirPath The path to the directory to test for read and write * access. * * @return True if we have both read and write access, false otherwise. */ public static boolean hasReadWriteAccess(Path dirPath) { Path p = null; try { p = Files.createTempFile(dirPath, TEMP_FILE_NAME, TEMP_FILE_EXT); return (p.toFile().canRead() && p.toFile().canWrite()); } catch (IOException ex) { return false; } finally { if (p != null) { try { p.toFile().delete(); } catch (Exception ignored) { } } } } /** * Prevents instantiation of this utility class. */ private FileUtil() { } }