001 /* 002 * Created on Sep 23, 2006 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 005 * the License. You may obtain a copy of the License at 006 * 007 * http://www.apache.org/licenses/LICENSE-2.0 008 * 009 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 010 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 011 * specific language governing permissions and limitations under the License. 012 * 013 * Copyright @2006 the original author or authors. 014 */ 015 package org.fest.util; 016 017 import static java.io.File.separator; 018 import static org.fest.util.Arrays.isEmpty; 019 import static org.fest.util.Closeables.close; 020 import static org.fest.util.Flushables.flush; 021 import static org.fest.util.Strings.*; 022 023 import java.io.File; 024 import java.io.IOException; 025 import java.io.OutputStream; 026 import java.io.Writer; 027 import java.util.ArrayList; 028 import java.util.List; 029 030 /** 031 * Understands utility methods related to files. 032 * 033 * @author Yvonne Wang 034 * @author Alex Ruiz 035 */ 036 public class Files { 037 038 /** 039 * Returns the names of the files inside the specified directory. 040 * @param dirName the name of the directory to start the search from. 041 * @param recurse if <code>true</code>, we will look in subdirectories. 042 * @return the names of the files inside the specified directory. 043 * @throws IllegalArgumentException if the given directory name does not point to an existing directory. 044 */ 045 public static List<String> fileNamesIn(String dirName, boolean recurse) { 046 File dir = new File(dirName); 047 if (!dir.isDirectory()) 048 throw new IllegalArgumentException(concat(quote(dirName), " is not a directory or does not exist")); 049 return fileNamesIn(dir, recurse); 050 } 051 052 /** 053 * Returns the names of the files inside the specified directory. 054 * @param dir the name of the directory to start the search from. 055 * @param recurse if <code>true</code>, we will look in subdirectories. 056 * @return the names of the files inside the specified directory. 057 */ 058 private static List<String> fileNamesIn(File dir, boolean recurse) { 059 List<String> scriptNames = new ArrayList<String>(); 060 File[] existingFiles = dir.listFiles(); 061 if (isEmpty(existingFiles)) return scriptNames; 062 for (File existingFile : existingFiles) { 063 if (existingFile.isDirectory()) { 064 if (recurse) scriptNames.addAll(fileNamesIn(existingFile, recurse)); 065 continue; 066 } 067 String filename = existingFile.getAbsolutePath(); 068 if (!scriptNames.contains(filename)) scriptNames.add(filename); 069 } 070 return scriptNames; 071 } 072 073 /** 074 * Returns the system's temporary folder. 075 * @return the system's temporary folder. 076 * @throws FilesException if this method cannot find or create the system's temporary folder. 077 */ 078 public static File temporaryFolder() { 079 File temp = new File(temporaryFolderPath()); 080 if (!temp.isDirectory()) throw new FilesException("Unable to find temporary folder"); 081 return temp; 082 } 083 084 /** 085 * Returns the path of the system's temporary folder. This method appends the system's file separator at the end of 086 * the path. 087 * @return the path of the system's temporary folder. 088 */ 089 public static String temporaryFolderPath() { 090 return append(separator).to(System.getProperty("java.io.tmpdir")); 091 } 092 093 /** 094 * Creates a new file in the system's temporary folder. The name of the file will be the result of: 095 * <pre> 096 * concat(String.valueOf(System.currentTimeMillis()), ".txt"); 097 * </pre> 098 * @return the created file. 099 */ 100 public static File newTemporaryFile() { 101 String tempFileName = concat(String.valueOf(System.currentTimeMillis()), ".txt"); 102 return newFile(concat(temporaryFolderPath(), tempFileName)); 103 } 104 105 /** 106 * Creates a new folder in the system's temporary folder. The name of the folder will be the result of: 107 * <pre> 108 * System.currentTimeMillis(); 109 * </pre> 110 * @return the created file. 111 */ 112 public static File newTemporaryFolder() { 113 String tempFileName = String.valueOf(System.currentTimeMillis()); 114 return newFolder(concat(temporaryFolderPath(), tempFileName)); 115 } 116 117 /** 118 * Creates a new file using the given path. 119 * @param path the path of the new file. 120 * @return the new created file. 121 * @throws FilesException if the path belongs to an existing non-empty directory. 122 * @throws FilesException if the path belongs to an existing file. 123 * @throws FilesException if any I/O error is thrown when creating the new file. 124 */ 125 public static File newFile(String path) { 126 File file = new File(path); 127 if (file.isDirectory() && !isEmpty(file.list())) 128 throw cannotCreateNewFile(path, "a non-empty directory was found with the same path"); 129 try { 130 if (!file.createNewFile()) throw cannotCreateNewFile(path, "a file was found with the same path"); 131 } catch (IOException e) { 132 throw cannotCreateNewFile(path, e); 133 } 134 return file; 135 } 136 137 /** 138 * Creates a new folder using the given path. 139 * @param path the path of the new folder. 140 * @return the new created folder. 141 * @throws FilesException if the path belongs to an existing non-empty directory. 142 * @throws FilesException if the path belongs to an existing file. 143 * @throws FilesException if any I/O error is thrown when creating the new folder. 144 */ 145 public static File newFolder(String path) { 146 File file = new File(path); 147 if (file.isDirectory() && !isEmpty(file.list())) 148 throw cannotCreateNewFile(path, "a non-empty directory was found with the same path"); 149 try { 150 if (!file.mkdir()) throw cannotCreateNewFile(path, "a file was found with the same path"); 151 } catch (Exception e) { 152 throw cannotCreateNewFile(path, e); 153 } 154 return file; 155 } 156 157 private static FilesException cannotCreateNewFile(String path, String reason) { 158 throw cannotCreateNewFile(path, reason, null); 159 } 160 161 private static FilesException cannotCreateNewFile(String path, Exception cause) { 162 throw cannotCreateNewFile(path, null, cause); 163 } 164 165 private static FilesException cannotCreateNewFile(String path, String reason, Exception cause) { 166 String message = concat("Unable to create the new file ", quote(path)); 167 if (!Strings.isEmpty(reason)) message = concat(message, ": ", reason); 168 if (cause != null) throw new FilesException(message, cause); 169 throw new FilesException(message); 170 } 171 172 /** 173 * Flushes and closes the given <code>{@link Writer}</code>. Any I/O errors catched by this method are ignored and 174 * not rethrown. 175 * @param writer the writer to flush and close. 176 */ 177 public static void flushAndClose(Writer writer) { 178 if (writer == null) return; 179 flush(writer); 180 close(writer); 181 } 182 183 /** 184 * Flushes and closes the given <code>{@link OutputStream}</code>. Any I/O errors catched by this method are ignored 185 * and not rethrown. 186 * @param out the output stream to flush and close. 187 */ 188 public static void flushAndClose(OutputStream out) { 189 if (out == null) return; 190 flush(out); 191 close(out); 192 } 193 194 /** 195 * Returns the current directory. 196 * @return the current directory. 197 * @throws FilesException if the current directory cannot be obtained. 198 */ 199 public static File currentFolder() { 200 try { 201 return new File(".").getCanonicalFile(); 202 } catch (IOException e) { 203 throw new FilesException("Unable to get current directory", e); 204 } 205 } 206 207 /** 208 * Deletes the given file or directory. 209 * @param file the file or directory to delete. 210 */ 211 public static void delete(File file) { 212 if (file.isFile()) { 213 file.delete(); 214 return; 215 } 216 if (!file.isDirectory()) return; 217 for (File f : file.listFiles()) delete(f); 218 file.delete(); 219 } 220 221 private Files() {} 222 }