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