[Pharo-users] How to construct a multi-part file reference
udo.schneider at homeaddress.de
Sat May 7 04:46:50 EDT 2016
I remember running into similar problems because I didn't understand the
FileSystem philosophy ... and dealing with strings and concatenating
them is so much easier, right? :-)
After reading the chapter on FileSystem several times over and over
again the IMHO most important part of it to get the grasp of FileSystem
is on page 13
FileReference = FileSystem + Path
Paths and filesystems are the lowest level of the FileSystem API. A
FileReference combines a path and a filesystem into a single object
which provides a simpler protocol for working with files as we show in
the previous section. References implement the path protocol with
methods like /, parent and resolve:.
So in your example ‘/home/jfabry’ and ‘test/code/foo.txt’ are just
(relative) path strings. They do not reference anything outside of the
context of a filesystem. The hard part for me to understand was the fact
that a path may not be unique. The same path might reference different
files in different filesystems.
This is especially strange coming from a *nix background where there is
only one filesystem.
But even on Windows one could argue that the OS nowadays only knows one
filesystem: You can reference any file via a UNC path ... drives,
shares, partitions, URIs and other filesystems are simply aliases into
the UNC space.
The nice thing of the FileSystem API is it's ability to transparently
use files in-Memory, archives, FTP, WebDav, S3 ... . All from within
Pharo with the same consistent API. E.g. if you have the
you can do something like:
"Obtain a FTP FileSystem"
fs := FileSystem ftp: 'ftp://ftp.2600.com'.
"Get working directory"
wd := fs workingDirectory .
"Print the following expression!"
(wd / 'pub' / 'publications' / 'n0way') children.
(wd / 'pub' / 'publications' / 'n0way' / 'README') contents.
"Open a FileList on the FileSystem"
FileList openOn: wd.
"Remember to close if you are finished!"
So to make a long story short: Both your strings contain paths. So we
have to convert them into Paths and somehow combine them with a
FileSystem to get a valid FileReference:
"I changed the second string to demonstrate dealing with different
dirString := '/home/jfabry'.
fileString := 'test\code\foo.txt'.
"Convert path strings to Paths"
dirPath := Path from: dirString delimiter: $/.
filePath := Path from: fileString delimiter: $\.
"Please note the Paths do not reference anything. We have no FileSystem
"The FileSystem our Paths will be resolved within"
diskFs := FileSystem disk.
"FileReference for the root directory in the FS"
rootRef := diskFs root.
"Resolve our Paths in the Context of the Reference"
dirRef := rootRef resolve: dirPath.
fileRef := dirRef resolve: filePath. "File @ /home/jfabry/test/code/foo.txt"
"Please note the fileRef printString. 'File' denotes the FileSystem -
not the fact that this is a file! Then you have the path after the at sign"
I hope this helps.
Final advice: In Pharo you should *never never never* assume that a Path
is "enough" to reference a file. You will always need the context (it's
FileSystem) as well. And that's exactly what a FileReference (see above)
is. So if you only have a Path it's questionable to assume that you can
simply combine it with a DiskFileSystem to get a valid reference. What
if the Path references a file in a ZIP in-Memory archive? Trying to
access the Path on disk will yield no result. So always always always
store/pass a FileReference if possible!!!!
I did run into that issue in the past with archive/net FileSystems where
some dev tools at one point extracted the Path from the FileReference
and passed them arround. Down the stack some other methods needed the
file contents. Because only the Path was passed they assumed they could
retrieve the contents by simply combining it with a DiskFileSystem ...
On 07/05/16 00:33, Johan Fabry wrote:
> Hi all,
> I have a question about the filesystem that I could not resolve using the documentation. The problem is as follows: I have a file reference that is 2 separate strings that I need to join into one complete file ref but I don’t know how because I don’t know what the platform’s file separator is.
> For example, on a unix-like OS I get ‘/home/jfabry’ as one part and ‘test/code/foo.txt’ as the other part, and I need to construct a FileReference to ‘/home/jfabry/test/code/foo.txt’.On M$ I guess this would be 'C:\users\jfabry' and ‘test\code\foo.txt’, so I need to construct FileReference to 'C:\users\jfabry\test\code\foo.txt’
> And the bingo question is: what do I do if I both strings use different kinds of separators?
> ---> Save our in-boxes! http://emailcharter.org <---
> Johan Fabry - http://pleiad.cl/~jfabry
> PLEIAD and RyCh labs - Computer Science Department (DCC) - University of Chile
More information about the Pharo-users