1 package fr.ifremer.quadrige2.core.dao.technical;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import fr.ifremer.quadrige2.core.exception.Quadrige2TechnicalException;
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.apache.commons.net.io.CopyStreamListener;
29 import org.apache.commons.net.io.Util;
30 import org.apache.commons.vfs2.FileObject;
31 import org.nuiton.jaxx.application.ApplicationIOUtil;
32
33 import java.io.File;
34 import java.io.IOException;
35 import java.io.InputStream;
36 import java.io.OutputStream;
37 import java.nio.file.*;
38 import java.nio.file.attribute.BasicFileAttributes;
39
40
41
42
43 public class Files {
44
45 private static final Log log = LogFactory.getLog(Files.class);
46 private static final int DEFAULT_IO_BUFFER_SIZE = 1048576;
47
48 private Files() {
49
50 }
51
52
53
54
55
56
57
58
59
60 public static void copy(String sourceFileName, String destinationFileName, CopyStreamListener progressMonitor) throws IOException {
61
62 FileObject sourceFile = ApplicationIOUtil.resolveFile(sourceFileName, "Can't resolve " + sourceFileName);
63 FileObject destinationFile = ApplicationIOUtil.resolveFile(destinationFileName, "Can't resolve " + destinationFileName);
64
65 try (InputStream sourceFileIn = sourceFile.getContent().getInputStream();
66 OutputStream destinationFileOut = destinationFile.getContent().getOutputStream()) {
67 Util.copyStream(sourceFileIn, destinationFileOut, DEFAULT_IO_BUFFER_SIZE, sourceFile.getContent().getSize(), progressMonitor);
68 }
69 }
70
71
72
73
74
75
76
77 public static void cleanDirectory(File directory, String failMessage) {
78
79 Path path = directory.toPath();
80 int nbAttempt = 0;
81 IOException lastException = null;
82 while (isDirectoryNotEmpty(path) && nbAttempt < 10) {
83 nbAttempt++;
84 try {
85 java.nio.file.Files.walkFileTree(path, new RecursiveDeleteFileVisitor(path));
86 lastException = null;
87 } catch (NoSuchFileException ignored) {
88 } catch (AccessDeniedException ade) {
89 if (java.nio.file.Files.exists(Paths.get(ade.getFile()))) {
90 lastException = ade;
91 break;
92 }
93 } catch (IOException e) {
94 lastException = e;
95
96 try {
97 Thread.sleep(500);
98 } catch (InterruptedException ignored) {
99 }
100 }
101 }
102 if (lastException != null) {
103 throw new Quadrige2TechnicalException(failMessage, lastException);
104 }
105 if (log.isWarnEnabled() && nbAttempt > 1) {
106 log.warn(String.format("cleaning the directory '%s' successful after %d attempts", directory.getAbsolutePath(), nbAttempt));
107 }
108 }
109
110 private static boolean isDirectoryNotEmpty(final Path path) {
111 if (!java.nio.file.Files.isDirectory(path)) {
112 return false;
113 }
114 try {
115 try (DirectoryStream<Path> dirStream = java.nio.file.Files.newDirectoryStream(path)) {
116 return dirStream.iterator().hasNext();
117 }
118 } catch (IOException e) {
119 return false;
120 }
121 }
122
123 private static class RecursiveDeleteFileVisitor extends SimpleFileVisitor<Path> {
124
125 private final Path root;
126
127 private RecursiveDeleteFileVisitor(Path root) {
128 this.root = root;
129 }
130
131 @Override
132 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
133
134
135 java.nio.file.Files.deleteIfExists(file);
136 return FileVisitResult.CONTINUE;
137 }
138
139 @Override
140 public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
141
142
143 if (dir == root) {
144 return FileVisitResult.TERMINATE;
145 }
146
147
148 java.nio.file.Files.deleteIfExists(dir);
149 return FileVisitResult.CONTINUE;
150 }
151
152 }
153 }