PageRenderTime 89ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/com/corecanarias/agora/lib/FileUtil.java

https://bitbucket.org/fidox/agora-lib
Java | 330 lines | 200 code | 34 blank | 96 comment | 18 complexity | 8c0e69e8214e4a3322e6131879d3fad2 MD5 | raw file
  1. package com.corecanarias.agora.lib;
  2. import java.beans.PropertyChangeEvent;
  3. import java.beans.PropertyChangeListener;
  4. import java.io.File;
  5. import java.io.FileFilter;
  6. import java.io.FileInputStream;
  7. import java.io.FileNotFoundException;
  8. import java.io.FileOutputStream;
  9. import java.io.FilenameFilter;
  10. import java.io.IOException;
  11. import java.io.InputStream;
  12. import java.io.OutputStream;
  13. import java.math.BigInteger;
  14. import java.security.MessageDigest;
  15. import java.security.NoSuchAlgorithmException;
  16. import java.util.List;
  17. import org.apache.commons.lang.StringUtils;
  18. import org.mozilla.universalchardet.UniversalDetector;
  19. /**
  20. * Utils for file and directory management
  21. *
  22. * @author ieb@corecanarias.com
  23. *
  24. */
  25. public class FileUtil {
  26. /**
  27. * Create a temp directory so-aware
  28. * @param prefix
  29. * @param sufix
  30. * @return
  31. */
  32. public static final File createTempDir(String prefix, String sufix) {
  33. File tempDir;
  34. try {
  35. tempDir = File.createTempFile(prefix, sufix);
  36. tempDir.delete();
  37. tempDir.mkdir();
  38. return tempDir;
  39. } catch (IOException e) {
  40. throw new RuntimeException(e);
  41. }
  42. }
  43. public static final boolean equals(File f1, File f2) {
  44. if(f1 == f2) {
  45. return true;
  46. }
  47. if(f1 == null || f2 == null) {
  48. return false;
  49. }
  50. return f1.getAbsolutePath().equals(f2.getAbsolutePath());
  51. }
  52. /**
  53. * Delete a directory and all its content
  54. * @param path Directory to delete
  55. */
  56. public static final void deleteDir(File path) {
  57. if (path.exists()) {
  58. File[] files = path.listFiles();
  59. for (int i = 0; i < files.length; i++) {
  60. if (files[i].isDirectory()) {
  61. deleteDir(files[i]);
  62. files[i].delete();
  63. } else {
  64. files[i].delete();
  65. }
  66. }
  67. path.delete();
  68. }
  69. }
  70. /**
  71. * Delete a single file
  72. * @param file The absolute path to the file
  73. */
  74. public static final void deleteFile(String file) {
  75. deleteFile(new File(file));
  76. }
  77. /**
  78. * Delete a single file
  79. *
  80. * @param file The File object pointing to the file
  81. */
  82. public static final void deleteFile(File file) {
  83. file.delete();
  84. }
  85. public static final String getCharset(File file) throws IOException {
  86. FileInputStream fis = new FileInputStream(file);
  87. UniversalDetector detector = new UniversalDetector(null);
  88. byte[] buf = new byte[4096];
  89. int nread;
  90. while ((nread = fis.read(buf)) > 0 && !detector.isDone()) {
  91. detector.handleData(buf, 0, nread);
  92. }
  93. detector.dataEnd();
  94. fis.close();
  95. return detector.getDetectedCharset();
  96. }
  97. /**
  98. * Copy a InputStream into another and notify the process of the copy. You are encourged to open and close the streams.
  99. * Also you can cancel the copy by setting the propagationId of any PROGRESS PropertyChangeEvent to CANCEL
  100. *
  101. * @param in Source stream
  102. * @param out Dest stream
  103. * @param progress Listener to get the progress notifications
  104. * @return True if it was sucessfully copied false if it was cancelled by the user
  105. * @throws IOException In case of read/write problems
  106. */
  107. public static final boolean copyInputStream(InputStream in, OutputStream out, PropertyChangeListener progress) throws IOException {
  108. byte[] buffer = new byte[1024];
  109. int len;
  110. long count = 0;
  111. while ((len = in.read(buffer)) >= 0) {
  112. count += len;
  113. if(progress != null) {
  114. PropertyChangeEvent evt = new PropertyChangeEvent(progress, "PROGRESS", len, count);
  115. progress.propertyChange(evt);
  116. if(StringUtils.equals((String)evt.getPropagationId(), "CANCEL")) {
  117. return false;
  118. }
  119. }
  120. out.write(buffer, 0, len);
  121. }
  122. return true;
  123. }
  124. /**
  125. * Copy a file to another and notify the process of the copy. Also you can cancel the copy by setting
  126. * the propagationId of any PROGRESS PropertyChangeEvent to CANCEL
  127. *
  128. * @param orig The absolute path to orig file
  129. * @param dest The absolute path to dest file
  130. * @param progress Listener to get the progress notifications
  131. * @return True it was sucessfully copied, false in another case.
  132. */
  133. public static final boolean copyFiles(String orig, String dest, PropertyChangeListener progress) {
  134. try {
  135. FileInputStream forig = new FileInputStream(orig);
  136. FileOutputStream fdest = new FileOutputStream(dest);
  137. FileUtil.copyInputStream(forig, fdest, progress);
  138. } catch (FileNotFoundException e) {
  139. return false;
  140. } catch (IOException e) {
  141. return false;
  142. }
  143. return true;
  144. }
  145. /**
  146. * Check if two files are equals.
  147. *
  148. * This method use md5 to the comparasion
  149. * @param fname1
  150. * @param fname2
  151. * @return
  152. * @throws NoSuchAlgorithmException
  153. * @throws IOException
  154. */
  155. public static boolean isSameFile(String fname1, String fname2) throws NoSuchAlgorithmException, IOException {
  156. return StringUtils.equals(md5File(new File(fname1)), md5File(new File(fname2)));
  157. }
  158. /**
  159. * Test if any file with a name starting with the name of filename exists in the directory
  160. *
  161. * @param dir The directory where to lookup
  162. * @param filename The absolute path where extract the name of the file
  163. * @return True if exists a file with a name starting with the filename name, false in another case.
  164. */
  165. public static final boolean filenameExists(String dir, String filename) {
  166. final String fname = new File(filename).getName();
  167. String[] res = new File(dir).list(new FilenameFilter() {
  168. @Override
  169. public boolean accept(File dir, String name) {
  170. return StringUtils.startsWith(name, fname);
  171. }
  172. });
  173. return res.length > 0;
  174. }
  175. /**
  176. * Test if any file with a name starting with the name of filename exists in the directory. No taking in account the extenions
  177. * of the file.
  178. *
  179. * @param dir The directory where to lookup
  180. * @param filename The absolute path where extract the name of the file
  181. * @return True if exists a file with a name starting with the filename name, false in another case.
  182. */
  183. public static final boolean filenameNoExtensionExists(String dir, String filename) {
  184. final String fname = new File(filename).getName();
  185. String[] res = new File(dir).list(new FilenameFilter() {
  186. @Override
  187. public boolean accept(File dir, String name) {
  188. String[] parts = FileUtil.splitFilename(fname);
  189. return StringUtils.startsWith(name, parts[0]);
  190. }
  191. });
  192. return res.length > 0;
  193. }
  194. /**
  195. * Separate the filename itself and the extension of a filename
  196. * @param filename The name of the file
  197. * @return An array with two position the first one is the filename and the second one is the extension
  198. */
  199. public static final String[] splitFilename(String filename) {
  200. String[] res = new String[2];
  201. int idx = filename.lastIndexOf(".");
  202. res[0] = filename.substring(0, idx);
  203. res[1] = filename.substring(idx);
  204. return res;
  205. }
  206. /**
  207. * MD5 of a stream
  208. *
  209. * @param file The file
  210. * @return An string representing the MD5 sum.
  211. * @throws IOException
  212. * @throws NoSuchAlgorithmException
  213. */
  214. public static final String md5(InputStream stream) throws IOException, NoSuchAlgorithmException {
  215. MessageDigest m = MessageDigest.getInstance("MD5");
  216. byte[] buffer = new byte[1024];
  217. int len;
  218. long count = 0;
  219. while((len = stream.read(buffer)) >= 0) {
  220. count += len;
  221. m.update(buffer, 0, len);
  222. }
  223. BigInteger i = new BigInteger(1, m.digest());
  224. if(stream.markSupported()) {
  225. stream.reset();
  226. }
  227. return String.format("%1$032x", i);
  228. }
  229. /**
  230. * MD5 of a file
  231. *
  232. * @param file The file
  233. * @return An string representing the MD5 sum.
  234. * @throws IOException
  235. * @throws NoSuchAlgorithmException
  236. */
  237. public static final String md5File(File file) throws IOException, NoSuchAlgorithmException {
  238. FileInputStream forig = new FileInputStream(file);
  239. return md5(forig);
  240. }
  241. /**
  242. * Check in linux system if a file is a symbolic link.
  243. * @param f The file to test
  244. *
  245. * @return True if it's a symbolic link false otherwise
  246. */
  247. public static final boolean isLinuxSymLink(File f) {
  248. if("\\".equals(File.separator)) {
  249. return false;
  250. }
  251. try {
  252. File canonicalFile;
  253. if (f.getParent() == null) {
  254. canonicalFile = f;
  255. } else {
  256. File canonicalDir = f.getParentFile().getCanonicalFile();
  257. canonicalFile = new File(canonicalDir, f.getName());
  258. }
  259. return !canonicalFile.getCanonicalFile().equals(canonicalFile.getAbsoluteFile());
  260. } catch(IOException e) {
  261. throw new RuntimeException(e);
  262. }
  263. }
  264. /**
  265. * Lookup for files/directories inside of a root directory recursively.
  266. *
  267. * The difference with Apache FileUtils is that this method can find directories too
  268. * not only files like the FileUtils in commons-io
  269. *
  270. * @param result An initialized list where it will put the Files found
  271. * @param root The root directory where to search
  272. * @param filter The filter applied in the search
  273. *
  274. * @See org.apache.commons.io.FileUtils
  275. */
  276. public static final void listDirectories(List<File> result, File root, FileFilter filter) {
  277. File[] dirs = root.listFiles(new FileFilter() {
  278. @Override
  279. public boolean accept(File file) {
  280. return file.isDirectory() && !FileUtil.isLinuxSymLink(file);
  281. }
  282. });
  283. if(dirs != null) {
  284. for(File d: dirs) {
  285. if(filter == null || filter.accept(d)) {
  286. result.add(d);
  287. }
  288. listDirectories(result, d, filter);
  289. }
  290. }
  291. }
  292. }