ws_e_c421
ws_e_c421

Reputation: 1113

Is there a standard, cross-platform way to handle and store relative file paths?

I am writing a Firefox add-on that stores and opens files stored within a base directory (a directory that the user selects as a preference). I would like to make it easy for the user to copy that directory and move it to another computer (possibly switching between OSX, Linux and Windows).

The first way I thought to do this was just to store the part of the file path after the base directory, and, if the operating system is Windows, to change all \'s to /'s. Then when using the path, the stored path is concatenated onto the current base directory (after replacing all /'s with \'s if the operating system is Windows).

Is this reasonable or a bad practice? If someone used a \ in an OSX path (I think that's possible, but maybe those slashes are some other character that looks like the file separator character \?), it could lead to unwanted behavior. One alternative I thought of was to use nsIFile and build the relative path by recursively using parent and leafName to pick out each directory name and save it to a string with something like "" in between, which I could then replace with the appropriate path separator for the operating system. This seems more robust than my first method, but maybe there is a simpler, more standard solution?

Upvotes: 1

Views: 551

Answers (2)

Noitidart
Noitidart

Reputation: 37238

I came across this in my searches. There's a new solution now. It's OS.File: https://developer.mozilla.org/en-US/docs/JavaScript_OS.File/OS.File_for_the_main_thread

Upvotes: 0

Wladimir Palant
Wladimir Palant

Reputation: 57651

You don't need to invent your own solution, there is nsILocalFile.getRelativeDescriptor(). Example:

var file1 = Components.classes["@mozilla.org/file/local;1"]
                      .createInstance(Components.interfaces.nsILocalFile);
file1.initWithPath("c:\\foo\\");

var file2 = Components.classes["@mozilla.org/file/local;1"]
                      .createInstance(Components.interfaces.nsILocalFile);
file2.initWithPath("c:\\foo\\bar\\test.txt");
alert(file2.getRelativeDescriptor(file1));

This code will display bar/test.txt. To get from a relative descriptor to a file you use setRelativeDescriptor():

file2.setRelativeDescriptor(file1, "bar/test.txt");
alert(file2.path);

The relative descriptors are cross-platform, you can move the directory do a different OS and the descriptor won't change.

Upvotes: 1

Related Questions