ac1d4c18eff9227ebb02f5af6376081886ac7795
[mir.git] / source / mir / util / FileRoutines.java
1 /*
2  * Copyright (C) 2001-2006 The Mir-coders group
3  *
4  * This file is part of Mir.
5  *
6  * Mir is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Mir is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Mir; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * In addition, as a special exception, The Mir-coders gives permission to link
21  * the code of this program with  any library licensed under the Apache Software License,
22  * and distribute linked combinations including the two.  You must obey the
23  * GNU General Public License in all respects for all of the code used other than
24  * the above mentioned libraries.  If you modify this file, you may extend this
25  * exception to your version of the file, but you are not obligated to do so.
26  * If you do not wish to do so, delete this exception statement from your version.
27  */
28 package mir.util;
29
30 import gnu.regexp.RE;
31
32 import java.io.*;
33 import java.util.Arrays;
34 import java.util.Collections;
35 import java.util.List;
36
37 public class FileRoutines {
38   protected static final int FILE_COPY_BUFFER_SIZE = 65536;
39
40   protected FileRoutines() {
41   }
42
43   /**
44    * Copy a file
45    */
46   public static void copyFile(File aSourceFile, File aDestinationFile) throws IOException {
47     BufferedInputStream inputStream;
48     BufferedOutputStream outputStream;
49     int nrBytesRead;
50     byte[] buffer = new byte[FILE_COPY_BUFFER_SIZE];
51
52     inputStream = new BufferedInputStream(new FileInputStream(aSourceFile));
53     try {
54       File directory = new File(aDestinationFile.getParent());
55       if (directory != null && !directory.exists()) {
56         directory.mkdirs();
57       }
58       outputStream = new BufferedOutputStream(new FileOutputStream(aDestinationFile), 8192);
59       try {
60         do {
61           nrBytesRead = inputStream.read(buffer);
62           if (nrBytesRead > 0)
63             outputStream.write(buffer, 0, nrBytesRead);
64         }
65         while (nrBytesRead >= 0);
66       }
67       finally {
68         outputStream.close();
69       }
70     }
71     finally {
72       inputStream.close();
73     }
74   }
75
76   /**
77    * Copy a directory recursively
78    */
79   public static void copyDirectory(File aSourceDirectory, File aDestinationDirectory) throws IOException {
80     int i;
81     File sourceFile;
82     File destinationFile;
83     File[] files = aSourceDirectory.listFiles();
84
85     if (!aDestinationDirectory.exists())
86       aDestinationDirectory.mkdirs();
87
88     for (i = 0; i < files.length; i++) {
89       sourceFile = files[i];
90       destinationFile = new File(aDestinationDirectory, sourceFile.getName());
91       if (sourceFile.isDirectory()) {
92         if (!destinationFile.exists())
93           destinationFile.mkdir();
94         copyDirectory(sourceFile, destinationFile);
95       }
96       else {
97         copyFile(sourceFile, destinationFile);
98       }
99     }
100   }
101
102   /**
103    * Copy a file or directory. If the source is a file and the destination
104    * a directory, the file is copied using the same file name into the\
105    * directory.
106    *
107    * @param aSource the source file
108    * @param aDestination the destination file
109    */
110   public static void copy(File aSource, File aDestination) throws IOException {
111     if (aSource.isDirectory()) {
112       copyDirectory(aSource, aDestination);
113     }
114     else if (aDestination.isDirectory()) {
115       copyFile(aSource, new File(aDestination, aSource.getName()));
116     }
117     else {
118       copyFile(aSource, aDestination);
119     }
120   }
121
122   /**
123    * Copy the contents of an {@link InputStream} to a {@link File}
124    */
125   public static void copy(InputStream aSource, File aDestination) throws IOException {
126     BufferedOutputStream outputStream =
127         new BufferedOutputStream(new FileOutputStream(aDestination), 8192);
128
129     int read;
130     byte[] buf = new byte[8 * 1024];
131
132     while ((read = aSource.read(buf)) != -1) {
133       outputStream.write(buf, 0, read);
134     }
135
136     aSource.close();
137     outputStream.close();
138   }
139
140   /**
141    * Moves a {@link File} to a new location
142    */
143   public static void move(File aSource, File aDestination) throws IOException {
144     aDestination.getParentFile().mkdirs();
145     if (!aSource.renameTo(aDestination)) {
146       byte[] buffer = new byte[16384];
147       FileInputStream inputStream = new FileInputStream(aSource);
148       FileOutputStream outputStream = new FileOutputStream(aDestination);
149       try {
150         int count = inputStream.read(buffer);
151         while (count > 0) {
152           outputStream.write(buffer, 0, count);
153           count = inputStream.read(buffer);
154         }
155       }
156       finally {
157         outputStream.close();
158         inputStream.close();
159       }
160       aSource.delete();
161     }
162   }
163
164   public static class RegExpFileFilter implements FilenameFilter {
165     private RE expression;
166
167     public RegExpFileFilter(String anExpression) {
168       try {
169         expression = new RE(anExpression);
170       }
171       catch (Throwable t) {
172         throw new RuntimeException(t.getMessage());
173       }
174     }
175
176     public boolean accept(File aDir, String aName) {
177       return expression.isMatch(aName) && !new File(aDir, aName).isDirectory();
178     }
179   }
180
181   public static class DirectoryFilter implements FilenameFilter {
182     public DirectoryFilter() {
183     }
184
185     public boolean accept(File aDir, String aName) {
186       return new File(aDir, aName).isDirectory();
187     }
188   }
189
190   /**
191    * Return all files in a directory
192    *
193    * @param aDirectory The directory to list
194    * @param aFilter    the filter to apply to files
195    * @return a <code>List</code> of filenames of type <code>String</code>
196    */
197   public static List getDirectoryContentsAsList(File aDirectory, FilenameFilter aFilter) {
198     Object[] contents = aDirectory.list(aFilter);
199
200     if (contents == null) {
201       return Collections.EMPTY_LIST;
202     }
203
204     return Arrays.asList(contents);
205   }
206
207   /**
208    * Return the extension of a path. (e.g. <code>getExtension("example.txt")</code> will
209    * return <code>"txt"</code>
210    */
211   public static String getExtension(String aPath) {
212     int position = aPath.lastIndexOf('.');
213     if (position >= 0) {
214       return aPath.substring(position + 1);
215     }
216     return "";
217   }
218
219   public static boolean isAbsolutePath(String aPath) {
220     return new File(aPath).isAbsolute();
221   }
222
223   /**
224    * Transforms an absolute or relative path into an absolute
225    * {@link File}.
226    *
227    * @param aBasePath The base path to use for relative paths
228    * @param aPath     The path to transform
229    * @return An absolute representation of the supplied path
230    */
231   public static File getAbsoluteOrRelativeFile(File aBasePath, String aPath) {
232     if (isAbsolutePath(aPath)) {
233       return new File(aPath);
234     }
235
236     return new File(aBasePath, aPath);
237   }
238
239   /**
240    * Reads the content of a file into an array of bytes
241    */
242   public static byte[] readFileIntoByteArray(File aFile) throws IOException {
243     InputStream input = new FileInputStream(aFile);
244     ByteArrayOutputStream result = new ByteArrayOutputStream();
245
246     IORoutines.copyStream(input, result);
247
248     return result.toByteArray();
249   }
250
251         /**
252          * Reads the content of a file into an array of bytes
253          */
254         public static void writeByteArrayIntoFile(byte[] anArray, File aFile) throws IOException {
255           OutputStream output = new FileOutputStream(aFile);
256
257           try {
258                 ByteArrayInputStream input = new ByteArrayInputStream(anArray);
259                 try {
260                   IORoutines.copyStream(input, output);
261                 }
262                 finally {
263                         input.close();
264                 }
265           }
266           finally {
267                 output.close();
268           }
269         }
270
271
272
273   /**
274    * Creates all parent directories of a file if they do not exist
275    */
276   public static void createParentDirectories(File aFile) {
277     if (aFile.getParentFile() != null && !aFile.getParentFile().exists()) {
278       aFile.getParentFile().mkdirs();
279     }
280   }
281 }