/framework/src/play/libs/Files.java

https://github.com/branaway/play · Java · 196 lines · 140 code · 17 blank · 39 comment · 21 complexity · 48176fbc36a65809b93a29bb56679d9d MD5 · raw file

  1. package play.libs;
  2. import org.apache.commons.io.FileUtils;
  3. import org.apache.commons.io.IOUtils;
  4. import play.exceptions.UnexpectedException;
  5. import java.io.*;
  6. import java.util.Enumeration;
  7. import java.util.zip.ZipEntry;
  8. import java.util.zip.ZipFile;
  9. import java.util.zip.ZipOutputStream;
  10. import static org.apache.commons.io.FileUtils.copyInputStreamToFile;
  11. /**
  12. * Files utils
  13. */
  14. public class Files {
  15. /**
  16. * Characters that are invalid in Windows OS file names (Unix only forbids '/' character)
  17. */
  18. public static final char[] ILLEGAL_FILENAME_CHARS = {34, 60, 62, 124, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
  19. 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 58, 42, 63, 92, 47};
  20. public static final char ILLEGAL_FILENAME_CHARS_REPLACE = '_';
  21. /**
  22. * Just copy a file
  23. * @param from
  24. * @param to
  25. */
  26. public static void copy(File from, File to) {
  27. if (from.getAbsolutePath().equals(to.getAbsolutePath())) {
  28. return;
  29. }
  30. try {
  31. FileUtils.copyFile(from, to);
  32. } catch (Exception e) {
  33. throw new RuntimeException(e);
  34. }
  35. }
  36. /**
  37. * Just delete a file. If the file is a directory, it's work.
  38. * @param file The file to delete
  39. */
  40. public static boolean delete(File file) {
  41. if (file.isDirectory()) {
  42. return deleteDirectory(file);
  43. } else {
  44. return file.delete();
  45. }
  46. }
  47. /**
  48. * Recursively delete a directory.
  49. */
  50. public static boolean deleteDirectory(File path) {
  51. if (path.exists()) {
  52. File[] files = path.listFiles();
  53. for (File file: files) {
  54. if (file.isDirectory()) {
  55. deleteDirectory(file);
  56. } else {
  57. file.delete();
  58. }
  59. }
  60. }
  61. return (path.delete());
  62. }
  63. public static boolean copyDir(File from, File to) {
  64. try {
  65. FileUtils.copyDirectory(from, to);
  66. return true;
  67. } catch (IOException e) {
  68. return false;
  69. }
  70. }
  71. public static void unzip(File from, File to) {
  72. try {
  73. String outDir = to.getCanonicalPath();
  74. ZipFile zipFile = new ZipFile(from);
  75. try {
  76. Enumeration<? extends ZipEntry> entries = zipFile.entries();
  77. while (entries.hasMoreElements()) {
  78. ZipEntry entry = entries.nextElement();
  79. if (entry.isDirectory()) {
  80. new File(to, entry.getName()).mkdir();
  81. continue;
  82. }
  83. File f = new File(to, entry.getName());
  84. if (!f.getCanonicalPath().startsWith(outDir)) {
  85. throw new IOException("Corrupted zip file");
  86. }
  87. f.getParentFile().mkdirs();
  88. copyInputStreamToFile(zipFile.getInputStream(entry), f);
  89. }
  90. }
  91. finally {
  92. zipFile.close();
  93. }
  94. } catch (IOException e) {
  95. throw new RuntimeException(e);
  96. }
  97. }
  98. public static void zip(File directory, File zipFile) {
  99. try {
  100. FileOutputStream os = new FileOutputStream(zipFile);
  101. try {
  102. ZipOutputStream zos = new ZipOutputStream(os);
  103. try {
  104. zipDirectory(directory, directory, zos);
  105. }
  106. finally {
  107. zos.close();
  108. }
  109. }
  110. finally {
  111. os.close();
  112. }
  113. } catch (Exception e) {
  114. throw new UnexpectedException(e);
  115. }
  116. }
  117. /**
  118. * Replace all characters that are invalid in file names on Windows or Unix operating systems
  119. * with {@link Files#ILLEGAL_FILENAME_CHARS_REPLACE} character.
  120. * <p>
  121. * This method makes sure your file name can successfully be used to write new file to disk.
  122. * Invalid characters are listed in {@link Files#ILLEGAL_FILENAME_CHARS} array.
  123. *
  124. * @param fileName File name to sanitize
  125. * @return Sanitized file name (new String object) if found invalid characters or same string if not
  126. */
  127. public static String sanitizeFileName(String fileName) {
  128. return sanitizeFileName(fileName, ILLEGAL_FILENAME_CHARS_REPLACE);
  129. }
  130. /**
  131. * Replace all characters that are invalid in file names on Windows or Unix operating systems
  132. * with passed in character.
  133. * <p>
  134. * This method makes sure your file name can successfully be used to write new file to disk.
  135. * Invalid characters are listed in {@link Files#ILLEGAL_FILENAME_CHARS} array.
  136. *
  137. * @param fileName File name to sanitize
  138. * @param replacement character to use as replacement for invalid chars
  139. * @return Sanitized file name (new String object) if found invalid characters or same string if not
  140. */
  141. public static String sanitizeFileName(String fileName, char replacement) {
  142. if (fileName == null || fileName.isEmpty()) {
  143. return fileName;
  144. }
  145. char[] chars = fileName.toCharArray();
  146. boolean changed = false;
  147. for (int i = 0; i < chars.length; i++) {
  148. char c = chars[i];
  149. if (c < 128) {
  150. for (char illegal : ILLEGAL_FILENAME_CHARS) {
  151. if (c == illegal) {
  152. chars[i] = replacement;
  153. changed = true;
  154. break;
  155. }
  156. }
  157. }
  158. }
  159. return changed ? new String(chars) : fileName;
  160. }
  161. static void zipDirectory(File root, File directory, ZipOutputStream zos) throws Exception {
  162. for (File item : directory.listFiles()) {
  163. if (item.isDirectory()) {
  164. zipDirectory(root, item, zos);
  165. } else {
  166. FileInputStream fis = new FileInputStream(item);
  167. try {
  168. String path = item.getAbsolutePath().substring(root.getAbsolutePath().length() + 1);
  169. ZipEntry anEntry = new ZipEntry(path);
  170. zos.putNextEntry(anEntry);
  171. IOUtils.copyLarge(fis, zos);
  172. }
  173. finally {
  174. fis.close();
  175. }
  176. }
  177. }
  178. }
  179. }