001 /*
002 Copyright (c) 2009 Olivier Chafik, All Rights Reserved
003
004 This file is part of JNAerator (http://jnaerator.googlecode.com/).
005
006 JNAerator is free software: you can redistribute it and/or modify
007 it under the terms of the GNU General Public License as published by
008 the Free Software Foundation, either version 3 of the License, or
009 (at your option) any later version.
010
011 JNAerator is distributed in the hope that it will be useful,
012 but WITHOUT ANY WARRANTY; without even the implied warranty of
013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014 GNU General Public License for more details.
015
016 You should have received a copy of the GNU General Public License
017 along with JNAerator. If not, see <http://www.gnu.org/licenses/>.
018 */
019 package com.ochafik.io;
020 import java.io.BufferedOutputStream;
021 import java.io.File;
022 import java.io.FileFilter;
023 import java.io.FileInputStream;
024 import java.io.FileOutputStream;
025 import java.io.FilenameFilter;
026 import java.io.IOException;
027 import java.io.InputStream;
028 import java.util.ArrayList;
029 import java.util.Collection;
030 import java.util.HashMap;
031 import java.util.HashSet;
032 import java.util.Iterator;
033 import java.util.Map;
034 import java.util.Vector;
035
036 import com.ochafik.util.progress.ProgressModel;
037
038 public class FileUtils {
039 public static Collection<File> getFilesCollection(File files[], FileFilter ff, boolean recursive) {
040 Collection<File> col=new ArrayList<File>();
041 for (int i=0,len=files.length;i<len;i++) {
042 File fi=files[i];
043 if (fi.isDirectory()) {
044 if (recursive) {
045 Collection<File> c=new HashSet<File>(getFilesCollection(fi.listFiles(),ff,true));
046 if (c!=null) col.addAll(c);
047 } else {
048 File ffs[]=fi.listFiles();
049 for (int j=0,len2=ffs.length;j<len2;j++) {
050 File ffj=ffs[j];
051 if (!ffj.isDirectory()&&!(ff!=null&&!ff.accept(ffj))) col.add(ffj);
052 }
053 }
054 } else if (!(ff!=null&&!ff.accept(fi))) {
055 col.add(fi);
056 //System.out.print("#");
057 }
058 }
059 return col;
060 }
061 public static final File getUniqueFile(String name,File rep) {
062 return getNonExistingFile(name,rep);
063 }
064 public static final File getNonExistingFile(String name,File rep) {
065 File tmp;
066 if (name==null||name.equals("")) name=" ";
067 else {
068 tmp=new File(rep,name);
069 if (!tmp.exists()) return tmp;
070 }
071 int i=1,k=name.lastIndexOf(".");
072 if (k<0) {
073 do {
074 tmp=new File(rep,name+String.valueOf(i++));
075 } while (tmp.exists());
076 return tmp;
077 } else {
078 String deb=name.substring(0,k),fin=name.substring(k);
079 do {
080 tmp=new File(rep,deb+String.valueOf(i++)+fin);
081 } while (tmp.exists());
082 return tmp;
083 }
084 }
085 public static final File getNextAlphabetSameTypeFile(File f) {
086 File rep=f.getParentFile();
087
088 final String n=f.getName();
089 int k=n.lastIndexOf(".");
090 String[] sn;
091 if (k<0)
092 sn=rep.list(new FilenameFilter() {
093 public boolean accept(File fi,String na) {
094 return true;
095 }
096 });
097 else {
098 final String ext=n.substring(k);
099 sn=rep.list(new FilenameFilter() {
100 public boolean accept(File fi,String na) {
101 return na.endsWith(ext);
102 }
103 });
104 }
105 String min=null;
106 for (int i=0;i<sn.length;i++) {
107 String a=sn[i];
108 if (n.compareTo(a)<0) {
109 if (min==null||min.compareTo(a)>0) min=a;
110 }
111 }
112 return new File(rep,min);
113 }
114 public void moveFile(File src,File dest,ProgressModel pv) throws IOException {
115 try {
116 //BufferedInputStream in=new BufferedInputStream(new ProgressModel(new FileInputStream(src),pv));
117 InputStream in = new FileInputStream(src);
118 pv.setTitle("Déplacement de fichier");
119 pv.setComment(src.toString()+" -> "+dest.toString());
120 File papa=dest.getParentFile();
121 if (!papa.exists()) papa.mkdirs();
122 BufferedOutputStream out=new BufferedOutputStream(new FileOutputStream(dest));
123 byte b[]=new byte[2048];
124 int l;
125 while ((l=in.read(b))>0) out.write(b,0,l);
126 out.close();
127 in.close();
128 src.delete();
129 } catch (IOException ex) {
130 throw new IOException("Incapable de déplacer "+src.toString()+" vers "+dest.toString()+"\nCause :"+ex.toString());
131 }
132 }
133 public static void copyFile(File src,File dest,ProgressModel pv) throws IOException {
134 try {
135 //BufferedInputStream in=new BufferedInputStream(new ProgressModelInputStream(new FileInputStream(src),pv));
136 InputStream in = new FileInputStream(src);
137 //pv.setTitle("Copie de fichier");
138 //pv.setComment(src.toString()+" -> "+dest.toString());
139 File papa=dest.getParentFile();
140 if (papa!=null&&!papa.exists()) papa.mkdirs();
141 BufferedOutputStream out=new BufferedOutputStream(new FileOutputStream(dest));
142 byte b[]=new byte[2048];
143 int l;
144 while ((l=in.read(b))>0) out.write(b,0,l);
145 out.close();
146 in.close();
147 } catch (IOException ex) {
148 throw new IOException("Incapable de copier "+src.toString()+" vers "+dest.toString()+"\nCause :"+ex.toString());
149 }
150 }
151 /**
152 v Vector de File : contient tous les fichiers enfants de ceux de départ : les répertoires sont fouillés récursivement, les fichiers sont ajoutés.
153 stringDest : Vector de String : contiendra les noms de fichier relatifs, s'il est non nul.
154 */
155 public static final Vector<File> getFilesAndRelativeNames(Vector<File> v,String ext[],Vector<String> stringsDest) {
156 Vector<File> ret=new Vector<File>();
157
158 for (File f : v) {
159 if (f.isDirectory()) {
160 if (stringsDest==null) ret.addAll(getFilesAndRelativeNames(f,ext,null));
161 else {
162 Vector<String> rel=new Vector<String>();
163 Vector<File> r=getFilesAndRelativeNames(f,ext,rel);
164 String prefix=f.getName()+File.separator;
165 int rs=rel.size();
166 for (int j=0;j<rs;j++) {
167 stringsDest.addElement(prefix+((String)rel.elementAt(j)));
168 ret.addElement(r.elementAt(j));
169 }
170 }
171 } else {
172 if (ext==null) {
173 ret.addElement(f);
174 if (stringsDest!=null) stringsDest.addElement(f.getName());
175 } else {
176 ret.addElement(f);
177 if (stringsDest!=null) stringsDest.addElement(f.getName());
178 }
179 }
180 }
181 return ret;
182 }
183 public static final Vector<File> getFilesAndRelativeNames(File fi,String ext[],Vector<String> stringsDest) {
184 File fs[]=fi.listFiles();
185 Vector<File> ret=new Vector<File>();
186 for (int i=fs.length-1;i!=-1;i--) {
187 File f=fs[i];
188 if (f.isDirectory()) {
189 if (stringsDest==null) ret.addAll(getFilesAndRelativeNames(f,ext,null));
190 else {
191 Vector<String> rel=new Vector<String>();
192 Vector<File> r=getFilesAndRelativeNames(f,ext,rel);
193 String prefix=f.getName()+File.separator;
194 int rs=rel.size();
195 for (int j=0;j<rs;j++) {
196 stringsDest.addElement(prefix+((String)rel.elementAt(j)));
197 ret.addElement(r.elementAt(j));
198 }
199 }
200 } else {
201 if (ext==null) {
202 ret.addElement(f);
203 if (stringsDest!=null) stringsDest.addElement(f.getName());
204 } else {
205 String name=f.getName();//,nameLow=name.toLowerCase();
206 for (int j=ext.length-1;j!=-1;j--) {
207 if (name.endsWith(ext[j])) {
208 ret.addElement(f);
209 if (stringsDest!=null) stringsDest.addElement(f.getName());
210 break;
211 }
212 }
213 }
214 }
215 }
216 return ret;
217 }
218 public static final long totalFilesLength(Collection<?> v) throws IOException {
219 long l=0;
220 for (Iterator<?> it=v.iterator();it.hasNext();) //int i=v.size()-1;i!=-1;i--)
221 l+=((File)it.next()).length();
222 return l;
223 }
224 static final String currentDirPrefix="."+File.separator;
225 /**
226 Renvoie les associations 'fichier de départ'=>'fichier changé de hiérarchie'
227 */
228 public static final HashMap<File,File> relativiseFileStringsThenMapFilesToNewFiles(
229 Collection<?> sourceFileStrings,
230 File sourceBase,
231 File sourceDest) {
232
233 HashMap<File,File> ret=new HashMap<File,File>();
234 String absSrcBase=sourceBase.getAbsolutePath();
235 //absDestBase=destBase.getAbsolutePath();
236 int asbl=absSrcBase.length();
237 if (absSrcBase.endsWith(".")) absSrcBase=absSrcBase.substring(0,--asbl);
238
239 for (Iterator<?> it=sourceFileStrings.iterator();it.hasNext();) {
240 String st=it.next().toString();
241 String absSrcFile=(new File(st)).getAbsolutePath();
242 if (absSrcFile.startsWith(absSrcBase)) {
243 String cut=absSrcFile.substring(asbl);
244 if (cut.startsWith(currentDirPrefix)) cut=cut.substring(2);
245 ret.put(new File(st),new File(sourceDest,cut));
246 } else throw new IllegalArgumentException("file \""+absSrcFile+"\" is not based upon \""+absSrcBase+"\" !!!");
247 }
248 return ret;
249 }
250 /**
251 Renvoie les associations 'fichier de départ'=>'fichier relatif'
252 */
253 public static final HashMap<File,String> mapFilesToRelativeFilePaths(
254 Collection<?> sourceFiles,
255 File sourceBase) {
256
257 HashMap<File,String> ret=new HashMap<File,String>();
258 String absSrcBase=sourceBase.getAbsolutePath();
259 //absDestBase=destBase.getAbsolutePath();
260 int asbl=absSrcBase.length();
261 if (absSrcBase.endsWith(".")) absSrcBase=absSrcBase.substring(0,--asbl);
262 if (!absSrcBase.endsWith(File.separator)) {
263 absSrcBase+=File.separator;
264 asbl++;
265 }
266
267 for (Iterator<?> it=sourceFiles.iterator();it.hasNext();) {
268 File stFile=(File)it.next();
269 String absSrcFile=(stFile).getAbsolutePath();
270 if (absSrcFile.startsWith(absSrcBase)) {
271 String cut=absSrcFile.substring(asbl);
272 ret.put(stFile,cut);
273 } else throw new IllegalArgumentException("file \""+absSrcFile+"\" is not based upon \""+absSrcBase+"\" !!!");
274 }
275 return ret;
276 }
277 /**
278 Renvoie les associations 'fichier relatif'=>'fichier de départ'
279 */
280 public static final Map<?, ?> mapRelativeFilePathsToFiles(
281 Collection<?> sourceFiles,
282 File sourceBase,
283 Map<String,File> ret) {
284
285 if (ret==null) ret=new HashMap<String,File>();
286 String absSrcBase=sourceBase.getAbsolutePath();
287 //absDestBase=destBase.getAbsolutePath();
288 int asbl=absSrcBase.length();
289 if (absSrcBase.endsWith(".")) absSrcBase=absSrcBase.substring(0,--asbl);
290 if (!absSrcBase.endsWith(File.separator)) {
291 absSrcBase+=File.separator;
292 asbl++;
293 }
294
295 for (Iterator<?> it=sourceFiles.iterator();it.hasNext();) {
296 File stFile=(File)it.next();
297 String absSrcFile=(stFile).getAbsolutePath();
298 if (absSrcFile.startsWith(absSrcBase)) {
299 String cut=absSrcFile.substring(asbl);
300 ret.put(cut,stFile);
301 } else throw new IllegalArgumentException("file \""+absSrcFile+"\" is not based upon \""+absSrcBase+"\" !!!");
302 }
303 return ret;
304 }
305 public static final Collection<?> relativizeThenAnchor(
306 Collection<?> sourceFiles,
307 File sourceBase,
308 File destBase) {
309
310 Vector<File> ret=new Vector<File>();
311 String absSrcBase=sourceBase.getAbsolutePath();
312 //absDestBase=destBase.getAbsolutePath();
313 int asbl=absSrcBase.length();
314 if (absSrcBase.endsWith(".")) absSrcBase=absSrcBase.substring(0,--asbl);
315 if (!absSrcBase.endsWith(File.separator)) {
316 absSrcBase+=File.separator;
317 asbl++;
318 }
319 for (Iterator<?> it=sourceFiles.iterator();it.hasNext();) {
320 File stFile=(File)it.next();
321 //System.out.println(stFile);
322 String absSrcFile=(stFile).getAbsolutePath();
323 if (absSrcFile.startsWith(absSrcBase)) {
324 String cut=absSrcFile.substring(asbl);
325 if (cut.startsWith(File.separator)) {
326 System.out.println(absSrcBase+" et "+cut);
327 cut=cut.substring(1);
328 }
329 ret.add(destBase==null ? new File(cut) : new File(destBase,cut));
330 } else throw new IllegalArgumentException("file \""+absSrcFile+"\" is not based upon \""+absSrcBase+"\" !!!");
331 }
332 return ret;
333 }
334 public static final void copyFiles(Vector<File> ifilesV,File repDest,String[] exts,ProgressModel pv) throws IOException {
335 Vector<String> relV=new Vector<String>();
336 Vector<File> filesV=getFilesAndRelativeNames(ifilesV,exts,relV);
337 long length=totalFilesLength(filesV);
338 pv.setMaximum(length-1);
339 int nfiles=filesV.size();
340 pv.setTitle("Copie de fichiers");
341
342 byte b[]=new byte[4096];
343 int l;
344 for (Iterator<?> fit=filesV.iterator(),rit=relV.iterator();fit.hasNext();) {//int i=0;i<nfiles;i++) {
345 File src=(File)fit.next();//filesV.elementAt(i);
346 File dest=new File(repDest,(String)rit.next());//(String)relV.elementAt(i));
347 //BufferedInputStream in=new BufferedInputStream(new ProgressModelInputStream(new FileInputStream(src),pv));
348 InputStream in = new FileInputStream(src);
349 pv.setComment(src.toString()+" -> "+dest.toString());
350 File papa=dest.getParentFile();
351 if (!papa.exists()) papa.mkdirs();
352 BufferedOutputStream out=new BufferedOutputStream(new FileOutputStream(dest));
353 while ((l=in.read(b))>0) out.write(b,0,l);
354 out.close();
355 in.close();
356 }
357 pv.setComment(nfiles+(nfiles>1 ? " fichiers, total=" : " fichier, total=")+length);
358 }
359
360 }