2.5: The Main Entry Point - FileReference
- Page ID
- 43796
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)
( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\id}{\mathrm{id}}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\kernel}{\mathrm{null}\,}\)
\( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\)
\( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\)
\( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)
\( \newcommand{\vectorA}[1]{\vec{#1}} % arrow\)
\( \newcommand{\vectorAt}[1]{\vec{\text{#1}}} % arrow\)
\( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vectorC}[1]{\textbf{#1}} \)
\( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)
\( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)
\( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)While FileSystem is based on multiple concepts and classes such as FileSystem
, Path
and FileReference
. FileReference
is the most important for an end-user. FileReference
offers a set of operations to manipulate files. So far, we have seen some basic operations. This section covers the more elaborated operations.
At the design level, a file reference (FileReference
) combines two low-level entities: a path (Path
) and a filesystem (FileSystem
) into a single object which provides a simple protocol to manipulate and handle files. A FileReference
implements many operations of FileSystem
(both are largely polymorphic), but without the need to track paths and filesystem separately.
FileReference information access
Once given a file reference you can access usual information using messages basename
, base
, extensions
...
| pf | pf := (FileSystem disk workingDirectory / 'package-cache' ) children second. → /Users/ducasse/Pharo/PharoHarvestingFixes/20/package-cache/AsmJit- IgorStasenko.66.mcz pf fullName → '/Users/ducasse/Pharo/PharoHarvestingFixes/20/package-cache/AsmJit- IgorStasenko.66.mcz' pf basename → 'AsmJit-IgorStasenko.66.mcz' pf basenameWithoutExtension → 'AsmJit-IgorStasenko.66' pf base → 'AsmJit-IgorStasenko' pf extension → 'mcz' pf extensions → an OrderedCollection('66' 'mcz')
Indicators. FileSystem introduces the notion of file reference indicators. An indicator is a visual clue conveying the type of the reference. For now three kind of indicators are implemented, '?' for a non existing reference, '/' for a directory, and the empty string for a file. FileReference
defines the message basenameWithIndicator
that takes advantage of indicators. The following expressions show its use.
pf basenameWithIndicator → 'AsmJit-IgorStasenko.66.mcz' pf parent basename → 'package-cache' pf parent basenameWithIndicator → 'package-cache/'
Path. When there is a need to access a portion of a path, the message pathSegments
returns the full name cut into path elements, as strings. Remember that from a design point of view, strings are considered as “dead” objects, so it is often better to deal with the real objects for example using the path message.
pf pathSegments → #('Users' 'ducasse' 'Pharo' 'PharoHarvestingFixes' '20' 'package-cache' ' AsmJit-IgorStasenko.66.mcz') pf path → Path / 'Users' / 'ducasse' / 'Pharo' / 'PharoHarvestingFixes' / '20' / 'package- cache' / 'AsmJit-IgorStasenko.66.mcz'
Sizes. FileReference provides also some way to access the size of the file.
pf humanReadableSize → '182.78 kB' pf size → 182778
File Information. You can get limited information about the file entry itself using creationTime
and permissions
. To get the full information you should access the entry itself using the message entry
.
| pf | pf := (FileSystem disk workingDirectory / 'package-cache' ) children second. pf creationTime. → 2012-06-10T10:43:19+02:00 pf modificationTime. → 2012-06-10T10:43:19+02:00 pf permissions → rw-r--r--
Entries are objects that represent all the metadata of a single file.
| pf | pf := (FileSystem disk workingDirectory / 'package-cache' ) children second. pf entry pf parent entries "returns all the entries of the children of the receiver"
Operating on files
There are several operations on files.
Deleting. delete
, deleteAll
, deleteAllChildren
, all delete the receiver and raise an error if it does not exist. delete
deletes the file, deleteAll
deletes the directory and its contents, deleteAllChildren
(which only deletes children of a directory). In addition, deleteIfAbsent:
executes a block when the file does not exist.
Finally ensureDelete
deletes the file but does not raise error if the file does not exist. Similarly ensureDeleteAllChildren
, ensureDeleteAll
do not raise exception when the receiver does not exist.
(FileSystem disk workingDirectory / 'paf') delete. → error (FileSystem disk workingDirectory / 'fooFolder') deleteAll. → error (FileSystem disk workingDirectory / 'fooFolder') ensureCreateDirectory. (FileSystem disk workingDirectory / 'fooFolder') deleteAll. (FileSystem disk workingDirectory / 'paf') deleteIfAbsent: [Warning signal: 'File did not exist']. (FileSystem disk workingDirectory / 'fooFolder2') deleteAllChildren. → error (FileSystem disk workingDirectory / 'fooFolder2') ensureCreateDirectory. (FileSystem disk workingDirectory / 'fooFolder2') deleteAllChildren.
Creating Directory. createDirectory
creates a new directory and raises an error if it already exists. ensureCreateDirectory
verifies that the directory does not exist and only creates it if necessary. ensureCreateFile
creates if necessary a file.
(FileSystem disk workingDirectory / 'paf' ) createDirectory. [(FileSystem disk workingDirectory / 'paf' ) createDirectory] on: DirectoryExists do: [:ex| true]. → true (FileSystem disk workingDirectory / 'paf' ) delete. (FileSystem disk workingDirectory / 'paf' ) ensureCreateDirectory. (FileSystem disk workingDirectory / 'paf' ) ensureCreateDirectory. (FileSystem disk workingDirectory / 'paf' ) isDirectory. → true
Moving/Copying files around. We can move files around using the message moveTo:
which expects a file reference.
(FileSystem disk workingDirectory / 'targetFolder') exist → false (FileSystem disk workingDirectory / 'paf') exist → false (FileSystem disk workingDirectory / 'paf' ) moveTo: (FileSystem disk workingDirectory / ' targetFolder') → Error (FileSystem disk workingDirectory / 'paf' ) ensureCreateFile. (FileSystem disk workingDirectory / 'targetFolder') ensureCreateDirectory. (FileSystem disk workingDirectory / 'paf' ) moveTo: (FileSystem disk workingDirectory / ' targetFolder' / 'paf'). (FileSystem disk workingDirectory / 'paf' ) exists. → false (FileSystem disk workingDirectory / 'targetFolder' / 'paf') exists. → true
Besides moving files, we can copy them. We can also use copyAllTo:
to copy files. Here, we copy the files contained in the source folder to the target one.
The message copyAllTo:
performs a deep copy of the receiver, to a location specified by the argument. If the receiver is a file, the file is copied. If the receiver is a directory, the directory and its contents will be copied recursively.
The argument must be a reference that does not exist; it will be created by the copy.
(FileSystem disk workingDirectory / 'sourceFolder') createDirectory. (FileSystem disk workingDirectory / 'sourceFolder' / 'pif') ensureCreateFile. (FileSystem disk workingDirectory / 'sourceFolder' / 'paf') ensureCreateFile. (FileSystem disk workingDirectory / 'targetFolder') createDirectory. (FileSystem disk workingDirectory / 'sourceFolder') copyAllTo: (FileSystem disk workingDirectory / 'targetFolder'). (FileSystem disk workingDirectory / 'targetFolder' / 'pif') exists. → true (FileSystem disk workingDirectory / 'targetFolder' / 'paf') exists. → true
The message copyAllTo:
can be used to copy a single file too:
(FileSystem disk workingDirectory / 'sourceFolder') ensureCreateDirectory. (FileSystem disk workingDirectory / 'sourceFolder' / 'pif') ensureCreateFile. (FileSystem disk workingDirectory / 'sourceFolder' / 'paf') ensureCreateFile. (FileSystem disk workingDirectory / 'targetFolder') ensureCreateDirectory. (FileSystem disk workingDirectory / 'sourceFolder' / 'paf') copyAllTo: (FileSystem disk workingDirectory / 'targetFolder' / 'paf'). (FileSystem disk workingDirectory / 'targetFolder' / 'paf') exists. → true. (FileSystem disk workingDirectory / 'targetFolder' / 'pif' ) exists. → false
Locator
Locators are late-bound references. They are left deliberately fuzzy, and are only resolved to a concrete reference when some file operation is performed. Instead of a filesystem and path, locators are made up of an origin and a path. An origin is an abstract filesystem location, such as the user’s home directory, the image file, or the VM executable. When it receives a message like isFile
, a locator will first resolve its origin, then resolve its path against the origin.
Locators make it possible to specify things like "an item named ’package-cache’ in the same directory as the image file" and have that specification remain valid even if the image is saved and moved to another directory, possibly on a different computer.
locator := FileLocator imageDirectory / 'package-cache'. locator printString. → ' {imageDirectory}/package-cache' locator resolve. → /Users/ducasse/Pharo/PharoHarvestingFixes/20/ package-cache locator isFile. → false locator isDirectory. → true
The following origins are currently supported:
imageDirectory
- the directory in which the image residesimage
- the image filechanges
- the changes filevmBinary
- the executable for the running virtual machinevmDirectory
- the directory containing the VM application (may not be the parent ofvmBinary
)home
- the user’s home directorydesktop
- the directory that holds the contents of the user’s desktopdocuments
- the directory where the user’s documents are stored (e.g.’/Users/colin/Documents’
)
Applications may also define their own origins, but the system will not be able to resolve them automatically. Instead, the user will be asked to manually choose a directory. This choice is then cached so that future resolution requests will not require user interaction.
absolutePath vs. path. The message absolutePath
returns the absolute path of the receiver. When the file reference is not virtual the messages path
and absolutePath
provide similar results. When the file is a late bound reference (instance of FileLocator
), absolutePath
resolves the file and returns the absolute path, while path returns an unresolved file reference as shown below.
(FileLocator image parent / 'package-cache') path → {image}/../package-cache (FileLocator image parent / 'package-cache') absolutePath → Path / 'Data' / 'Downloads' / 'Pharo-2.0' / 'package-cache' (FileLocator image parent / 'package-cache') absolutePath → Path / 'Data' / 'Downloads' / 'Pharo-2.0' / 'package-cache'
References and Locators also provide simple methods for dealing with whole directory trees.