HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Operations on files and their locks - code too bulky?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
operationstoocodefilesandbulkylockstheir

Problem

A couple of hours ago I asked a question on Stackoverflow to find out if there is a good way to delete files in a folder only if all files are indeed deletable and I got some good answers that led me (I think) in the right direction

Based on the two currently most upvoted answers I scrambled together the following code:

```
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileLock;
import java.util.ArrayList;
import java.util.List;

public class Main {

public static void main(String[] args) {
File directory = new File("T:\\download\\test\\1234");

if (safeDelete(directory)) {
System.out.println("All deleted");
} else {
System.out.println("All kept");
}
}

private static boolean safeDelete(File directory) {
if (directory == null || !directory.isDirectory()
|| !directory.canWrite()) {
return false;
}

// First get a lock on the directory itself
FileLock dirLock;
if ((dirLock = getLock(directory)) == null) {
return false;
}

List filesToDelete = new ArrayList<>();
List fileLocks = new ArrayList<>();

// Get a lock on all the files in the folder
for (File file : directory.listFiles()) {

FileLock lock;
if (file.canWrite() && ((lock = getLock(file)) != null)) {
filesToDelete.add(file);
fileLocks.add(lock);
} else {
System.out.println("Currently unable to write to "
+ file.getName());
releaseLocks(fileLocks);
return false;
}
}

// If we reach this line all the files are locked for us now
for (File file : filesToDelete) {
if (!file.delete()) {
System.out.println("IMPOSSIBLE");
}
}
releaseLocks(fileLoc

Solution

Why not use a class to hold both the file and the lock, so you don`t need to manage two Lists like:

public class SafeDirectory {

    private File directory = null;
    private FileLock lock = null;
    private List deleteableSafeFiles = new ArrayList<>();

    public SafeDirectory(String directoryPath) {
        directory = new File(directoryPath);
    }

    public boolean CanBeDeleted() {
        boolean canBeDeleted = false;
        if (directory != null && directory.canWrite() && directory.isDirectory()
                && ((lock = getLock(directory)) != null)) {

            canBeDeleted = true;
            for (File file : directory.listFiles()) {
                SafeFile safeFile = new SafeFile(file);

                if (safeFile.CanBeDeleted()) {
                    deleteableSafeFiles.add(safeFile);
                } else {
                    canBeDeleted = false;
                    System.out.println("Currently unable to write to "
                        + file.getName());
                    RelaseLock();
                    break;
                }
            }

        }
        return canBeDeleted;
    }

    public boolean Delete() {
        for (SafeFile safeFile : deleteableSafeFiles) {
            safeFile.Delete();
        }
        directory.delete();

        RelaseLock();
        return true;
    }

    private void RelaseLock() {
        for (SafeFile safeFile : deleteableSafeFiles) {
            releaseLock(safeFile.lock);
        }
        releaseLock(lock);
    }

    private boolean releaseLock(FileLock lock) {
        if (lock != null) {
            try {
                lock.release();
                System.out.println("Released lock on " + lock.toString());
                return true;
            } catch (IOException ex) {
                System.out.println("Cant release lock on " + lock.toString());
                return false;
            }
        }
        return true;

    }

    private static FileLock getLock(File file) {
        try {
            return new RandomAccessFile(file, "rw").getChannel().tryLock();

        } catch (IOException ex) {
            System.out.println(ex.toString());
            return null;
        }
    }

    private class SafeFile {

        private FileLock lock = null;
        private File file = null;

        SafeFile(File file) {
            this.file = file;
        }

        boolean CanBeDeleted() {
            return (file.canWrite() && ((lock = SafeDirectory.getLock(file)) != null));
        }

        boolean Delete() {
            return file.delete();
        }
    }
}

Code Snippets

public class SafeDirectory {

    private File directory = null;
    private FileLock lock = null;
    private List<SafeFile> deleteableSafeFiles = new ArrayList<>();

    public SafeDirectory(String directoryPath) {
        directory = new File(directoryPath);
    }

    public boolean CanBeDeleted() {
        boolean canBeDeleted = false;
        if (directory != null && directory.canWrite() && directory.isDirectory()
                && ((lock = getLock(directory)) != null)) {

            canBeDeleted = true;
            for (File file : directory.listFiles()) {
                SafeFile safeFile = new SafeFile(file);

                if (safeFile.CanBeDeleted()) {
                    deleteableSafeFiles.add(safeFile);
                } else {
                    canBeDeleted = false;
                    System.out.println("Currently unable to write to "
                        + file.getName());
                    RelaseLock();
                    break;
                }
            }

        }
        return canBeDeleted;
    }

    public boolean Delete() {
        for (SafeFile safeFile : deleteableSafeFiles) {
            safeFile.Delete();
        }
        directory.delete();

        RelaseLock();
        return true;
    }

    private void RelaseLock() {
        for (SafeFile safeFile : deleteableSafeFiles) {
            releaseLock(safeFile.lock);
        }
        releaseLock(lock);
    }

    private boolean releaseLock(FileLock lock) {
        if (lock != null) {
            try {
                lock.release();
                System.out.println("Released lock on " + lock.toString());
                return true;
            } catch (IOException ex) {
                System.out.println("Cant release lock on " + lock.toString());
                return false;
            }
        }
        return true;

    }

    private static FileLock getLock(File file) {
        try {
            return new RandomAccessFile(file, "rw").getChannel().tryLock();

        } catch (IOException ex) {
            System.out.println(ex.toString());
            return null;
        }
    }

    private class SafeFile {

        private FileLock lock = null;
        private File file = null;

        SafeFile(File file) {
            this.file = file;
        }

        boolean CanBeDeleted() {
            return (file.canWrite() && ((lock = SafeDirectory.getLock(file)) != null));
        }

        boolean Delete() {
            return file.delete();
        }
    }
}

Context

StackExchange Code Review Q#39960, answer score: 3

Revisions (0)

No revisions yet.