Close file lists

Though we could not reproduce an error even with real big file
structures (100 directories, containing each another 100 directories
with 100 files each), it may be safer to make sure the streams will
really be closed in the end and recommended in the javadoc description
for Files#list
(https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#list-java.nio.file.Path-)
This commit is contained in:
René Pfeuffer
2020-06-16 11:50:14 +02:00
parent b3040678c5
commit 7f3f47c4c8
5 changed files with 23 additions and 13 deletions

View File

@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.update.repository;
import sonia.scm.SCMContextProvider;
@@ -31,6 +31,7 @@ import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.function.Consumer;
import java.util.stream.Stream;
abstract class BaseMigrationStrategy implements MigrationStrategy.Instance {
@@ -50,9 +51,9 @@ abstract class BaseMigrationStrategy implements MigrationStrategy.Instance {
return contextProvider.getBaseDirectory().toPath().resolve("repositories").resolve(type);
}
Stream<Path> listSourceDirectory(Path sourceDirectory) {
try {
return Files.list(sourceDirectory);
void listSourceDirectory(Path sourceDirectory, Consumer<Stream<Path>> pathConsumer) {
try (Stream<Path> paths = Files.list(sourceDirectory)) {
pathConsumer.accept(paths);
} catch (IOException e) {
throw new UpdateException("could not read original directory", e);
}

View File

@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.update.repository;
import org.slf4j.Logger;
@@ -62,15 +62,17 @@ class CopyMigrationStrategy extends BaseMigrationStrategy {
private void copyData(Path sourceDirectory, Path targetDirectory) {
createDataDirectory(targetDirectory);
listSourceDirectory(sourceDirectory).forEach(
listSourceDirectory(sourceDirectory, paths -> paths.forEach(
sourceFile -> {
Path targetFile = targetDirectory.resolve(sourceFile.getFileName());
if (Files.isDirectory(sourceFile)) {
LOG.trace("traversing down into sub directory {}", sourceFile);
copyData(sourceFile, targetFile);
} else {
LOG.trace("copying file {} to {}", sourceFile, targetFile);
copyFile(sourceFile, targetFile);
}
}
);
));
}
}

View File

@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.update.repository;
import org.slf4j.Logger;
@@ -67,20 +67,23 @@ class InlineMigrationStrategy extends BaseMigrationStrategy {
private void moveData(Path sourceDirectory, Path targetDirectory, boolean deleteDirectory) {
createDataDirectory(targetDirectory);
listSourceDirectory(sourceDirectory)
listSourceDirectory(sourceDirectory, paths -> paths
.filter(sourceFile -> !targetDirectory.equals(sourceFile))
.forEach(
sourceFile -> {
Path targetFile = targetDirectory.resolve(sourceFile.getFileName());
if (Files.isDirectory(sourceFile)) {
LOG.trace("traversing down into sub directory {}", sourceFile);
moveData(sourceFile, targetFile, true);
} else {
LOG.trace("moving file {} to {}", sourceFile, targetFile);
moveFile(sourceFile, targetFile);
}
}
);
));
if (deleteDirectory) {
try {
LOG.trace("deleting source directory {}", sourceDirectory);
Files.delete(sourceDirectory);
} catch (IOException e) {
LOG.warn("could not delete source repository directory {}", sourceDirectory);

View File

@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.update.repository;
import org.slf4j.Logger;
@@ -83,17 +83,20 @@ class MoveMigrationStrategy extends BaseMigrationStrategy {
private void moveData(Path sourceDirectory, Path targetDirectory) {
createDataDirectory(targetDirectory);
listSourceDirectory(sourceDirectory).forEach(
listSourceDirectory(sourceDirectory, paths -> paths.forEach(
sourceFile -> {
Path targetFile = targetDirectory.resolve(sourceFile.getFileName());
if (Files.isDirectory(sourceFile)) {
LOG.trace("traversing down into sub directory {}", sourceFile);
moveData(sourceFile, targetFile);
} else {
LOG.trace("moving file {} to {}", sourceFile, targetFile);
moveFile(sourceFile, targetFile);
}
}
);
));
try {
LOG.trace("deleting source directory {}", sourceDirectory);
Files.delete(sourceDirectory);
} catch (IOException e) {
LOG.warn("could not delete source repository directory {}", sourceDirectory);