javafilereferencedirectorysynchronize

How to one-way synchronize files in two directory structures in java?


I have two folders, source and target, with files and possible subfolders(directory structure is assumed to be the same, subfolders and files can go into any depth) in them. We want to synchronize the target so that for all files:

Exists in source, but not in target -> new, copy over to target
Exists in target, but not in source -> deleted, delete from the target
Exists in both, but binary unequal -> changed, copy over from source
Exists in both, and is binary equal -> unchanged, leave be

One problem I have with this is checking for existence of a file(the return value of listFiles() doesn't seem to have contains() defined), but a far bigger obstacle is referencing the other directory structure. For example, how would I check if target folder contains file "foo.txt" while iterating through the source folder and finding it there? Here's what I have so far:

    public void synchronize(File source, File target) {
    //first loop; accounts for every case except deleted
    if (source.isDirectory()) {
        for (File i : source.listFiles()) {
            if (i.isDirectory()) {
                synchronize(i, /**i's equivalent subdirectory in target*/);
            }
            else if (/**i is new*/) {
                /**Copy i over to the appropriate target folder*/
            }
            else if (/**i is different*/) {
                /**copy i over from source to target*/
            }
            else {/**i is identical in both*/
                /**leave i in target alone*/
            }
        }
        for (File i : target.listFiles()) {
            if (/**i exists in the target but not in source*/) {
                /**delete in target*/
            }
        }
    }
}

EDIT(important): I thank you guys for all the answers, but the main problem remains unsolved: referring to the other directory, i.e. the stuff in the comments. h22's answer seem to be somewhere in the ballpark, but it's not sufficient, as explained in the comment below it. I'd be very grateful if someone could explain this in even smaller words. From experience, this is exactly the kind of problem that someone more java-savvy could solve in five minutes, whereas I would spend two frustrating weeks rediscovering America.


Solution

  • Only visit the source folder recursively. Strip the folder root and address the target location directly:

    String subPath = sourceFile.getAbsolutePath().substring(sourceRoot.length);
    File targetFile = new File(targetRoot + File.separator + subPath);
    
    if (targetFile.getParentFile().exists()) {
      targetFile.getParentFile().mkdirs();
    }
    // copy, etc
    

    Otherwise you may have difficulties if the target location is missing the required hierarchical folder structure that may go many directories in depth.