0

I am writing a backup program using Java and I would like to save the files and directories to the backup destination based on the absolute path names of the sources.

The backup program is supposed to work under different operating systems (Unix, Windows, Mac OS X), so I need to convert the absolute pathnames of the source files and directories.

So at the end I would like to convert an absolute source path to a regular sub-path of the destination. Let me give some examples.

Unix
Absolute source path: /home/thomas/data
Destination path: /backup
Effective destination: /backup/home/thomas/data

Windows
Absolute source path: c:\Documents and Settings\thomas
Destination path: e:\backup
Effective destination: e:\backup\c\Documents and Settings\thomas

I could use String replacement operations but I expect to run into several trouble and start a never ending correction story.

I think that Windows environment needs special handling because of the leading drive letters. Under *nix I could simply concatenate the two paths. Also note that the source path could be an UNC-path under Windows like \\share\data.

I have searched around and found several similar questions but none of them did answer mine (for example Is there a Java utility which will convert a String path to use the correct File separator char? or Convert Windows-style path into Unix path).

Maybe anybody has an idea or a hint for me or knows about a library that already does what I am seeking for.

Community
  • 1
  • 1
Thorsten
  • 315
  • 2
  • 7
  • Have you tried anything? –  Apr 01 '15 at 17:10
  • 1
    See https://docs.oracle.com/javase/7/docs/api/java/nio/file/Path.html#relativize%28java.nio.file.Path%29 – dhke Apr 01 '15 at 17:14
  • Hmm, maybe I do not understand, but the method in your link can be used to calcuted the "relation ship" between two paths. What I like to to is create a new sub-path based on an absolute source path and a destination path. – Thorsten Apr 01 '15 at 18:07

1 Answers1

1

If you're using Java 7 or later, the Paths class and its methods may be of use. Good overview here: https://docs.oracle.com/javase/tutorial/essential/io/pathOps.html

Specifically for your use case, you need subpath (gets a portion of a path) and resolve (combines two paths). I would try something like this:

Path backupRoot = Paths.get("/backup");
Path docRoot = Paths.get("/home/user1/docs");
// This line gets the full doc path without the root
Path docs = docRoot.subpath(0, docRoot.getNameCount());
// This line creates the path "/backup/home/user1/docs"
Path backupDocs = backupRoot.resolve(docs);
  • Yes I am using Java 7 and sure I am using Path and Paths classes from package "java.nio.file". But which method are you talking about? – Thorsten Apr 01 '15 at 18:11
  • Thank you very much for your investigations and your detailed answer. I tried a small example of your code with docRoot \\server\c$\Windows, c:\Windows, U:\ and it failed with an exception on the last one. Also note I would like to keep the root like "server/c$", "c:" or "u:" to be visible in my destination path. See my example in my question. – Thorsten Apr 03 '15 at 11:14
  • For this you could use `getRoot` on the docRoot path and take the first character, then insert an extra directory in your backup path (again using `resolve`) if the first character is a letter. – eggheadmike Apr 04 '15 at 01:03