Advertisement
Guest User

Untitled

a guest
Sep 23rd, 2017
428
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.30 KB | None | 0 0
  1. package io;
  2.  
  3. import java.io.Closeable;
  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.IOException;
  10. import java.nio.channels.FileChannel;
  11. import java.util.ArrayList;
  12. import java.util.List;
  13. import java.util.zip.ZipEntry;
  14. import java.util.zip.ZipOutputStream;
  15.  
  16. /**
  17. * General file manipulation utilities.
  18. * <p>
  19. * Facilities are provided in the following areas:
  20. * <ul>
  21. * <li>writing to a file
  22. * <li>reading from a file
  23. * <li>make a directory including parent directories
  24. * <li>copying files and directories
  25. * <li>deleting files and directories
  26. * <li>converting to and from a URL
  27. * <li>listing files and directories by filter and extension
  28. * <li>comparing file content
  29. * <li>file last changed date
  30. * <li>calculating a checksum
  31. * </ul>
  32. * <p>
  33. * Origin of code: Excalibur, Alexandria, Commons-Utils
  34. *
  35. * @author <a href="mailto:burton@relativity.yi.org">Kevin A. Burton</A>
  36. * @author <a href="mailto:sanders@apache.org">Scott Sanders</a>
  37. * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
  38. * @author <a href="mailto:Christoph.Reck@dlr.de">Christoph.Reck</a>
  39. * @author <a href="mailto:peter@apache.org">Peter Donald</a>
  40. * @author <a href="mailto:jefft@apache.org">Jeff Turner</a>
  41. * @author Matthew Hawthorne
  42. * @author <a href="mailto:jeremias@apache.org">Jeremias Maerki</a>
  43. * @author Stephen Colebourne
  44. * @author Ian Springer
  45. * @author Chris Eldredge
  46. * @author Jim Harrington
  47. * @author Niall Pemberton
  48. * @author Sandy McArthur
  49. * @version $Id: FileUtils.java 1003647 2010-10-01 20:53:59Z niallp $
  50. */
  51. public class FileUtils {
  52.  
  53. /**
  54. * Instances should NOT be constructed in standard programming.
  55. */
  56. public FileUtils () {
  57. super();
  58. }
  59. /**
  60. * The number of bytes in a kilobyte.
  61. */
  62. public static final long ONE_KB = 1024;
  63. /**
  64. * The number of bytes in a megabyte.
  65. */
  66. public static final long ONE_MB = ONE_KB * ONE_KB;
  67. /**
  68. * The number of bytes in a 50 MB.
  69. */
  70. private static final long FIFTY_MB = ONE_MB * 50;
  71. /**
  72. * The number of bytes in a gigabyte.
  73. */
  74. /**
  75. * The system separator character.
  76. */
  77. private static final char SYSTEM_SEPARATOR = File.separatorChar;
  78. /**
  79. * The Windows separator character.
  80. */
  81. private static final char WINDOWS_SEPARATOR = '\\';
  82.  
  83. /**
  84. * Copies a whole directory to a new location preserving the file dates.
  85. * <p>
  86. * This method copies the specified directory and all its child
  87. * directories and files to the specified destination.
  88. * The destination is the new location and name of the directory.
  89. * <p>
  90. * The destination directory is created if it does not exist.
  91. * If the destination directory did exist, then this method merges
  92. * the source with the destination, with the source taking precedence.
  93. * <p>
  94. * <strong>Note:</strong> This method tries to preserve the files' last
  95. * modified date/times using {@link File#setLastModified(long)}, however
  96. * it is not guaranteed that those operations will succeed.
  97. * If the modification operation fails, no indication is provided.
  98. *
  99. * @param srcDir an existing directory to copy, must not be <code>null</code>
  100. * @param destDir the new directory, must not be <code>null</code>
  101. *
  102. * @throws NullPointerException if source or destination is <code>null</code>
  103. * @throws IOException if source or destination is invalid
  104. * @throws IOException if an IO error occurs during copying
  105. * @since Commons IO 1.1
  106. */
  107. public static void copyDirectory (String srcDir, String destDir) throws IOException {
  108.  
  109. copyDirectory(new File(srcDir), new File(destDir), true);
  110. }
  111.  
  112. /**
  113. * Copies a whole directory to a new location.
  114. * <p>
  115. * This method copies the contents of the specified source directory
  116. * to within the specified destination directory.
  117. * <p>
  118. * The destination directory is created if it does not exist.
  119. * If the destination directory did exist, then this method merges
  120. * the source with the destination, with the source taking precedence.
  121. * <p>
  122. * <strong>Note:</strong> Setting <code>preserveFileDate</code> to
  123. * <code>true</code> tries to preserve the files' last modified
  124. * date/times using {@link File#setLastModified(long)}, however it is
  125. * not guaranteed that those operations will succeed.
  126. * If the modification operation fails, no indication is provided.
  127. *
  128. * @param srcDir an existing directory to copy, must not be <code>null</code>
  129. * @param destDir the new directory, must not be <code>null</code>
  130. * @param preserveFileDate true if the file date of the copy
  131. * should be the same as the original
  132. *
  133. * @throws NullPointerException if source or destination is <code>null</code>
  134. * @throws IOException if source or destination is invalid
  135. * @throws IOException if an IO error occurs during copying
  136. * @since Commons IO 1.1
  137. */
  138. private static void copyDirectory (File srcDir, File destDir,
  139. boolean preserveFileDate) throws IOException {
  140. copyDirectory(srcDir, destDir, null, preserveFileDate);
  141. }
  142.  
  143. /**
  144. * Copies a filtered directory to a new location.
  145. * <p>
  146. * This method copies the contents of the specified source directory
  147. * to within the specified destination directory.
  148. * <p>
  149. * The destination directory is created if it does not exist.
  150. * If the destination directory did exist, then this method merges
  151. * the source with the destination, with the source taking precedence.
  152. * <p>
  153. * <strong>Note:</strong> Setting <code>preserveFileDate</code> to
  154. * <code>true</code> tries to preserve the files' last modified
  155. * date/times using {@link File#setLastModified(long)}, however it is
  156. * not guaranteed that those operations will succeed.
  157. * If the modification operation fails, no indication is provided.
  158. *
  159. * <h4>Example: Copy directories only</h4>
  160. * <pre>
  161. * // only copy the directory structure
  162. * FileUtils.copyDirectory(srcDir, destDir, DirectoryFileFilter.DIRECTORY, false);
  163. * </pre>
  164. *
  165. * <h4>Example: Copy directories and txt files</h4>
  166. * <pre>
  167. * // Create a filter for ".txt" files
  168. * IOFileFilter txtSuffixFilter = FileFilterUtils.suffixFileFilter(".txt");
  169. * IOFileFilter txtFiles = FileFilterUtils.andFileFilter(FileFileFilter.FILE, txtSuffixFilter);
  170. *
  171. * // Create a filter for either directories or ".txt" files
  172. * FileFilter filter = FileFilterUtils.orFileFilter(DirectoryFileFilter.DIRECTORY, txtFiles);
  173. *
  174. * // Copy using the filter
  175. * FileUtils.copyDirectory(srcDir, destDir, filter, false);
  176. * </pre>
  177. *
  178. * @param srcDir an existing directory to copy, must not be <code>null</code>
  179. * @param destDir the new directory, must not be <code>null</code>
  180. * @param filter the filter to apply, null means copy all directories and files
  181. * @param preserveFileDate true if the file date of the copy
  182. * should be the same as the original
  183. *
  184. * @throws NullPointerException if source or destination is <code>null</code>
  185. * @throws IOException if source or destination is invalid
  186. * @throws IOException if an IO error occurs during copying
  187. * @since Commons IO 1.4
  188. */
  189. private static void copyDirectory (File srcDir, File destDir,
  190. FileFilter filter, boolean preserveFileDate) throws IOException {
  191. if (srcDir == null) {
  192. throw new NullPointerException("Source must not be null");
  193. }
  194. if (destDir == null) {
  195. throw new NullPointerException("Destination must not be null");
  196. }
  197. if (srcDir.exists() == false) {
  198. throw new FileNotFoundException("Source '" + srcDir + "' does not exist");
  199. }
  200. if (srcDir.isDirectory() == false) {
  201. throw new IOException("Source '" + srcDir + "' exists but is not a directory");
  202. }
  203. if (srcDir.getCanonicalPath().equals(destDir.getCanonicalPath())) {
  204. throw new IOException("Source '" + srcDir + "' and destination '" + destDir + "' are the same");
  205. }
  206.  
  207. // Cater for destination being directory within the source directory (see IO-141)
  208. List<String> exclusionList = null;
  209. if (destDir.getCanonicalPath().startsWith(srcDir.getCanonicalPath())) {
  210. File[] srcFiles = filter == null ? srcDir.listFiles() : srcDir.listFiles(filter);
  211. if (srcFiles != null && srcFiles.length > 0) {
  212. exclusionList = new ArrayList<String>(srcFiles.length);
  213. for (File srcFile : srcFiles) {
  214. File copiedFile = new File(destDir, srcFile.getName());
  215. exclusionList.add(copiedFile.getCanonicalPath());
  216. }
  217. }
  218. }
  219. doCopyDirectory(srcDir, destDir, filter, preserveFileDate, exclusionList);
  220. }
  221.  
  222. /**
  223. * Internal copy directory method.
  224. *
  225. * @param srcDir the validated source directory, must not be <code>null</code>
  226. * @param destDir the validated destination directory, must not be <code>null</code>
  227. * @param filter the filter to apply, null means copy all directories and files
  228. * @param preserveFileDate whether to preserve the file date
  229. * @param exclusionList List of files and directories to exclude from the copy, may be null
  230. * @throws IOException if an error occurs
  231. * @since Commons IO 1.1
  232. */
  233. private static void doCopyDirectory (File srcDir, File destDir, FileFilter filter,
  234. boolean preserveFileDate, List<String> exclusionList) throws IOException {
  235. // recurse
  236. File[] files = filter == null ? srcDir.listFiles() : srcDir.listFiles(filter);
  237. if (files == null) { // null if security restricted
  238. throw new IOException("Failed to list contents of " + srcDir);
  239. }
  240. if (destDir.exists()) {
  241. if (destDir.isDirectory() == false) {
  242. throw new IOException("Destination '" + destDir + "' exists but is not a directory");
  243. }
  244. }
  245. else if (destDir.mkdirs() == false) {
  246. throw new IOException("Destination '" + destDir + "' directory cannot be created");
  247. }
  248. if (destDir.canWrite() == false) {
  249. throw new IOException("Destination '" + destDir + "' cannot be written to");
  250. }
  251. for (File file : files) {
  252. File copiedFile = new File(destDir, file.getName());
  253. if (exclusionList == null || !exclusionList.contains(file.getCanonicalPath())) {
  254. if (file.isDirectory()) {
  255. doCopyDirectory(file, copiedFile, filter, preserveFileDate, exclusionList);
  256. }
  257. else {
  258. doCopyFile(file, copiedFile, preserveFileDate);
  259. }
  260. }
  261. }
  262.  
  263. // Do this last, as the above has probably affected directory metadata
  264. if (preserveFileDate) {
  265. destDir.setLastModified(srcDir.lastModified());
  266. }
  267. }
  268.  
  269. /**
  270. * Internal copy file method.
  271. *
  272. * @param srcFile the validated source file, must not be <code>null</code>
  273. * @param destFile the validated destination file, must not be <code>null</code>
  274. * @param preserveFileDate whether to preserve the file date
  275. * @throws IOException if an error occurs
  276. */
  277. private static void doCopyFile (File srcFile, File destFile, boolean preserveFileDate) throws IOException {
  278. if (destFile.exists() && destFile.isDirectory()) {
  279. throw new IOException("Destination '" + destFile + "' exists but is a directory");
  280. }
  281.  
  282. FileInputStream fis = null;
  283. FileOutputStream fos = null;
  284. FileChannel input = null;
  285. FileChannel output = null;
  286. try {
  287. fis = new FileInputStream(srcFile);
  288. fos = new FileOutputStream(destFile);
  289. input = fis.getChannel();
  290. output = fos.getChannel();
  291. long size = input.size();
  292. long pos = 0;
  293. long count = 0;
  294. while (pos < size) {
  295. count = (size - pos) > FIFTY_MB ? FIFTY_MB : (size - pos);
  296. pos += output.transferFrom(input, pos, count);
  297. }
  298. }
  299. finally {
  300. closeQuietly(output);
  301. closeQuietly(fos);
  302. closeQuietly(input);
  303. closeQuietly(fis);
  304. }
  305.  
  306. if (srcFile.length() != destFile.length()) {
  307. throw new IOException("Failed to copy full contents from '"
  308. + srcFile + "' to '" + destFile + "'");
  309. }
  310. if (preserveFileDate) {
  311. destFile.setLastModified(srcFile.lastModified());
  312. }
  313. }
  314.  
  315. /**
  316. * Unconditionally close a <code>Closeable</code>.
  317. * <p>
  318. * Equivalent to {@link Closeable#close()}, except any exceptions will be ignored.
  319. * This is typically used in finally blocks.
  320. * <p>
  321. * Example code:
  322. * <pre>
  323. * Closeable closeable = null;
  324. * try {
  325. * closeable = new FileReader("foo.txt");
  326. * // process closeable
  327. * closeable.close();
  328. * } catch (Exception e) {
  329. * // error handling
  330. * } finally {
  331. * IOUtils.closeQuietly(closeable);
  332. * }
  333. * </pre>
  334. *
  335. * @param closeable the object to close, may be null or already closed
  336. * @since Commons IO 2.0
  337. */
  338. private static void closeQuietly (Closeable closeable) {
  339. try {
  340. if (closeable != null) {
  341. closeable.close();
  342. }
  343. }
  344. catch (IOException ioe) {
  345. // ignore
  346. }
  347. }
  348.  
  349. /**
  350. * Deletes a directory recursively.
  351. *
  352. * @param directory directory to delete
  353. * @throws IOException in case deletion is unsuccessful
  354. */
  355. public static void deleteDirectory (File directory) throws IOException {
  356. if (!directory.exists()) {
  357. return;
  358. }
  359.  
  360. if (!isSymlink(directory)) {
  361. cleanDirectory(directory);
  362. }
  363.  
  364. if (!directory.delete()) {
  365. String message =
  366. "Unable to delete directory " + directory + ".";
  367. throw new IOException(message);
  368. }
  369. }
  370.  
  371. /**
  372. * Cleans a directory without deleting it.
  373. *
  374. * @param directory directory to clean
  375. * @throws IOException in case cleaning is unsuccessful
  376. */
  377. private static void cleanDirectory (File directory) throws IOException {
  378. if (!directory.exists()) {
  379. String message = directory + " does not exist";
  380. throw new IllegalArgumentException(message);
  381. }
  382.  
  383. if (!directory.isDirectory()) {
  384. String message = directory + " is not a directory";
  385. throw new IllegalArgumentException(message);
  386. }
  387.  
  388. File[] files = directory.listFiles();
  389. if (files == null) { // null if security restricted
  390. throw new IOException("Failed to list contents of " + directory);
  391. }
  392.  
  393. IOException exception = null;
  394. for (File file : files) {
  395. try {
  396. forceDelete(file);
  397. }
  398. catch (IOException ioe) {
  399. exception = ioe;
  400. }
  401. }
  402.  
  403. if (null != exception) {
  404. throw exception;
  405. }
  406. }
  407.  
  408. /**
  409. * Deletes a file. If file is a directory, delete it and all sub-directories.
  410. * <p>
  411. * The difference between File.delete() and this method are:
  412. * <ul>
  413. * <li>A directory to be deleted does not have to be empty.</li>
  414. * <li>You get exceptions when a file or directory cannot be deleted.
  415. * (java.io.File methods returns a boolean)</li>
  416. * </ul>
  417. *
  418. * @param file file or directory to delete, must not be <code>null</code>
  419. * @throws NullPointerException if the directory is <code>null</code>
  420. * @throws FileNotFoundException if the file was not found
  421. * @throws IOException in case deletion is unsuccessful
  422. */
  423. private static void forceDelete (File file) throws IOException {
  424. if (file.isDirectory()) {
  425. deleteDirectory(file);
  426. }
  427. else {
  428. boolean filePresent = file.exists();
  429. if (!file.delete()) {
  430. if (!filePresent) {
  431. throw new FileNotFoundException("File does not exist: " + file);
  432. }
  433. String message =
  434. "Unable to delete file: " + file;
  435. throw new IOException(message);
  436. }
  437. }
  438. }
  439.  
  440. /**
  441. * Determines whether the specified file is a Symbolic Link rather than an actual file.
  442. * <p>
  443. * Will not return true if there is a Symbolic Link anywhere in the path,
  444. * only if the specific file is.
  445. *
  446. * @param file the file to check
  447. * @return true if the file is a Symbolic Link
  448. * @throws IOException if an IO error occurs while checking the file
  449. * @since Commons IO 2.0
  450. */
  451. private static boolean isSymlink (File file) throws IOException {
  452. if (file == null) {
  453. throw new NullPointerException("File must not be null");
  454. }
  455. if (isSystemWindows()) {
  456. return false;
  457. }
  458. File fileInCanonicalDir = null;
  459. if (file.getParent() == null) {
  460. fileInCanonicalDir = file;
  461. }
  462. else {
  463. File canonicalDir = file.getParentFile().getCanonicalFile();
  464. fileInCanonicalDir = new File(canonicalDir, file.getName());
  465. }
  466.  
  467. if (fileInCanonicalDir.getCanonicalFile().equals(fileInCanonicalDir.getAbsoluteFile())) {
  468. return false;
  469. }
  470. else {
  471. return true;
  472. }
  473. }
  474.  
  475. /**
  476. * Determines if Windows file system is in use.
  477. *
  478. * @return true if the system is Windows
  479. */
  480. private static boolean isSystemWindows () {
  481. return SYSTEM_SEPARATOR == WINDOWS_SEPARATOR;
  482. }
  483. public final static String LINE_SEPARATOR = System.getProperty("line.separator");
  484. public final static String FILE_SEPARATOR = System.getProperty("file.separator");
  485.  
  486. /**
  487. * Zip up a directory
  488. *
  489. * @param directory
  490. * @param zipName
  491. * @throws IOException
  492. */
  493. public static void zipDir(String directory, String zipName) throws IOException {
  494. // create a ZipOutputStream to zip the data to
  495. if (!zipName.endsWith(".zip")) {
  496. zipName += ".zip";
  497. }
  498. ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipName));
  499. zipDir(directory, zos, "");
  500. // close the stream
  501. closeQuietly(zos);
  502. }
  503.  
  504. /**
  505. * Zip up a directory path
  506. * @param directory
  507. * @param zos
  508. * @param path
  509. * @throws IOException
  510. */
  511. private static void zipDir(String directory, ZipOutputStream zos, String path) throws IOException {
  512. File zipDir = new File(directory);
  513. // get a listing of the directory content
  514. String[] dirList = zipDir.list();
  515. byte[] readBuffer = new byte[2156];
  516. int bytesIn = 0;
  517. // loop through dirList, and zip the files
  518. for (int i = 0; i < dirList.length; ++i) {
  519. File f = new File(zipDir, dirList[i]);
  520. if (f.isDirectory()) {
  521. zipDir(f.getPath(), zos, path.concat(f.getName()).concat(FILE_SEPARATOR));
  522. continue;
  523. }
  524. FileInputStream fis = new FileInputStream(f);
  525. try {
  526. zos.putNextEntry(new ZipEntry(path.concat(f.getName())));
  527. bytesIn = fis.read(readBuffer);
  528. while (bytesIn != -1) {
  529. zos.write(readBuffer, 0, bytesIn);
  530. bytesIn = fis.read(readBuffer);
  531. }
  532. } finally {
  533. closeQuietly(fis);
  534. }
  535. }
  536.  
  537. }
  538. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement