001/* 002 * Copyright (C) Photon Vision. 003 * 004 * This program is free software: you can redistribute it and/or modify 005 * it under the terms of the GNU General Public License as published by 006 * the Free Software Foundation, either version 3 of the License, or 007 * (at your option) any later version. 008 * 009 * This program is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 * GNU General Public License for more details. 013 * 014 * You should have received a copy of the GNU General Public License 015 * along with this program. If not, see <https://www.gnu.org/licenses/>. 016 */ 017 018package org.photonvision.common.util.file; 019 020import java.io.File; 021import java.io.FileNotFoundException; 022import java.io.IOException; 023import java.nio.file.Files; 024import java.nio.file.NoSuchFileException; 025import java.nio.file.Path; 026import java.nio.file.attribute.PosixFileAttributes; 027import java.nio.file.attribute.PosixFilePermission; 028import java.util.Arrays; 029import java.util.Comparator; 030import java.util.HashSet; 031import java.util.Set; 032import org.photonvision.common.hardware.Platform; 033import org.photonvision.common.logging.LogGroup; 034import org.photonvision.common.logging.Logger; 035 036public class FileUtils { 037 private FileUtils() {} 038 039 private static final Logger logger = new Logger(FileUtils.class, LogGroup.General); 040 private static final Set<PosixFilePermission> allReadWriteExecutePerms = 041 new HashSet<>(Arrays.asList(PosixFilePermission.values())); 042 043 public static boolean deleteDirectory(Path path) { 044 try { 045 var files = Files.walk(path); 046 047 // delete directory including files and sub-folders 048 files 049 .sorted(Comparator.reverseOrder()) 050 .map(Path::toFile) 051 // .filter(File::isFile) // we want to delete directories and sub-dirs, too 052 .forEach((var file) -> deleteFile(file.toPath())); 053 054 // close the stream 055 files.close(); 056 057 return true; 058 } catch (IOException e) { 059 logger.error("Exception deleting files in " + path + "!", e); 060 return false; 061 } 062 } 063 064 /** 065 * Delete the file at the path. 066 * 067 * @param path file path to delete. 068 * @return whether the operation was successful. 069 */ 070 public static boolean deleteFile(Path path) { 071 try { 072 Files.delete(path); 073 return true; 074 } catch (FileNotFoundException | NoSuchFileException fe) { 075 logger.warn("Tried to delete file \"" + path + "\" but it did not exist"); 076 return false; 077 } catch (IOException e) { 078 logger.error("Exception deleting file \"" + path + "\"!", e); 079 return false; 080 } 081 } 082 083 /** 084 * Copy a file from a source to a new destination. 085 * 086 * @param src the file path to copy. 087 * @param dst the file path to replace. 088 * @return whether the operation was successful. 089 */ 090 public static boolean copyFile(Path src, Path dst) { 091 try { 092 Files.copy(src, dst); 093 return true; 094 } catch (IOException e) { 095 logger.error("Exception copying file " + src + " to " + dst + "!", e); 096 return false; 097 } 098 } 099 100 /** 101 * Replace the destination file with a new source. 102 * 103 * @param src the file path to replace with. 104 * @param dst the file path to replace. 105 * @return whether the operation was successful. 106 */ 107 public static boolean replaceFile(Path src, Path dst) { 108 boolean fileDeleted = deleteFile(dst); 109 boolean fileCopied = copyFile(src, dst); 110 return fileDeleted && fileCopied; 111 } 112 113 public static void setFilePerms(Path path) throws IOException { 114 if (Platform.isLinux()) { 115 File thisFile = path.toFile(); 116 Set<PosixFilePermission> perms = 117 Files.readAttributes(path, PosixFileAttributes.class).permissions(); 118 if (!perms.equals(allReadWriteExecutePerms)) { 119 logger.info("Setting perms on" + path); 120 Files.setPosixFilePermissions(path, perms); 121 var theseFiles = thisFile.listFiles(); 122 if (thisFile.isDirectory() && theseFiles != null) { 123 for (File subfile : theseFiles) { 124 setFilePerms(subfile.toPath()); 125 } 126 } 127 } 128 } 129 } 130 131 public static void setAllPerms(Path path) { 132 if (Platform.isLinux()) { 133 String command = String.format("chmod 777 -R %s", path.toString()); 134 try { 135 Process p = Runtime.getRuntime().exec(command); 136 p.waitFor(); 137 138 } catch (Exception e) { 139 logger.error("Setting perms failed!", e); 140 } 141 } else { 142 logger.info("Cannot set directory permissions on Windows!"); 143 } 144 } 145}