FileSystem question

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

FileSystem question

Stéphane Ducasse
I'm trying to move some of the examples of Coral from rio to filesystem and I get some questions.

Are there some examples (not tests)?
What is the difference between FSReference and FSPath?

For example how can I print in the Transcript all the files in my current dir?

Stef
_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: FileSystem question

Henrik Sperre Johansen


Den 12.02.2010 16:18, skrev Stéphane Ducasse:
> I'm trying to move some of the examples of Coral from rio to filesystem and I get some questions.
>
> Are there some examples (not tests)?
> What is the difference between FSReference and FSPath?
>
> For example how can I print in the Transcript all the files in my current dir?
>
> Stef
> _____________________________________
There's probably an easier way, but:

(FSDiskFilesystem current childrenAt: FSDiskFilesystem current
workingDirectory) do:
    [:each | each printOn: Transcript cr ].
Transcript flush.

Speaking of current dir...
FSDiskFilesystem current workingDirectory isWorkingDirectory -> false,
at least on Windows :)

Cheers,
Henry

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: FileSystem question

Lukas Renggli
In reply to this post by Stéphane Ducasse
> Are there some examples (not tests)?

Mason and Monticello 2 use it, as far as I know.

> What is the difference between FSReference and FSPath?

Did you read the class comments?

FSPath: I an abstract filesystem path, independent of the string
representation used to describe paths on a specific filesystem. I
provide methods for navigating the filesystem hierarchy and working
with absolute and relative paths. I only refer to a concrete file or
directory with regard to a specific filesystem.

FSReference: I combine a filesystem and path, which is sufficient to
refer to a concrete file or directory. I provide methods for
navigating my filesystem, performing filesystem operations and opening
and closing files.  I am the primary mechanism for working with files
and directories.

So most likely you are only interested in FSReference. FSPath is only
used for relative paths independent of the filesystem, or path that
cross or are independent of filesystem boundaries.

> For example how can I print in the Transcript all the files in my current dir?

FSDiskFilesystem current working children

Lukas

--
Lukas Renggli
http://www.lukas-renggli.ch

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: FileSystem question

Stéphane Ducasse
Of course I read them :)
this is the first thing I do.

>> Are there some examples (not tests)?
>
> Mason and Monticello 2 use it, as far as I know.

sure
Now I mean little examples in the sense of a little tutorial (see below the rio one).
I will probably start to write something like that for me.

>> What is the difference between FSReference and FSPath?
>
> Did you read the class comments?
>
> FSPath: I an abstract filesystem path, independent of the string
> representation used to describe paths on a specific filesystem. I
> provide methods for navigating the filesystem hierarchy and working
> with absolute and relative paths. I only refer to a concrete file or
> directory with regard to a specific filesystem.
>
> FSReference: I combine a filesystem and path, which is sufficient to
> refer to a concrete file or directory. I provide methods for
> navigating my filesystem, performing filesystem operations and opening
> and closing files.  I am the primary mechanism for working with files
> and directories.
>
> So most likely you are only interested in FSReference. FSPath is only
> used for relative paths independent of the filesystem, or path that
> cross or are independent of filesystem boundaries.

Ok so FSPath is a kind of internal representation of /usr/bin/

>
>> For example how can I print in the Transcript all the files in my current dir?
>
> FSDiskFilesystem current working children




>
Instantiating and Building Paths

The most concise method for creating a Rio is via: 1.below, the following are equivalent:
        • 'myFile.txt' asRio
        • Cwd / 'myFile.txt'
        • Rio / 'myFile.txt'
        • Rio new:'myFile.txt' - the verbose form
Rio's may be constucted using the #/ and #, operators like so.
Cwd / 'package-cache' / 'Rio-Core' , '-kph.20' , '.mcz'.

Deconstructing the Rio Path and File Name

Given myFile := Cwd / 'myFile.3.txt'.
        • myFile full => '/media/hda1/squeak/myFile.3.txt'
        • myFile fileName => 'myFile.3.txt'
        • myFile parent => '/media/hda1/squeak'
        • myFile base => 'myFile'
        • myFile version => 3
        • myFile ext => 'txt'
        • myFile path => ''.
        • myFile full split => #('/' 'media' 'hda1' 'squeak' 'myFile.3.txt')
Adjusting the Rio Path and File Name

Given myFile := Cwd / 'myFile.3.txt'.
(#parent: and #full: will set the path relative to the default directory).
        • myFile fileName: 'another.txt' => (Rio new:'another.txt').
        • myFile base: 'temp' => (Rio new: 'temp.3.txt').
        • myFile version: 4 => (Rio new: 'myFile.4.txt').
        • myFile ext: 'html' => (Rio new: 'myFile.3.html').
        • myFile parent: 'temp' => (Rio new: 'temp/myFile.3.txt')
        • myFile full: '/media/hda1/squeak/temp/myFile.3.txt' => (Rio new: 'temp/myFile.3.txt')
File Versions Helpers

If there exists a file, Cwd / 'temp.4.txt'. Then there are some utilities for obtaining the latest and next version file rio's.
        • 'temp.txt' asRio latestVersion => (Rio new: 'temp.4.txt').
        • 'temp.txt' asRio nextVersion => (Rio new: 'temp.5.txt').
A Word About Style

Rio may be used in two distinct styles. In addition to the traditional smalltalk cascading messages style, Rio supports a sentence like 'sequential' style. Whenever an example below uses the 'sequential' style for conciseness, suffice to say there is a traditional equivalent.

sequential:
 'myFile.zip' asRio zip addAll: '/tmp/files' asRio all files

cascading:
 (Rio new: 'myFile)
              setModeToZip;
              addAll: ((Rio new:'/tmp/files')
                                  setModeToRecursive;
                                  yourself) files;
              yourself.


Introducing Modes - 'Renaming' Mode

When a Rio is #setModeToRenaming, all of the above fileName and path manipulations are simultaneously actualized on disk. Below is an example using Rio's 'sequential' style for configuring modes:
        • myFile rename base: 'temp'. <= is equivalent to => 'myFile.3.txt' asRio renameTo: 'temp.3.txt'.
When a mode is set using 'cascading' style, (e.g. #setModeToRenaming) the mode flag is set on the given instance as you would expect. In contrast, when a mode is set in sequential style, a new instance is created, making the mode setting temporary for the remainer of that 'sequential sentence'. This convention applies to all modes. e.g.
        • cascading: (myFile setModeToRenaming; yourself) base:'temp'. – the renamng mode flag of myFile is set.
        • sequential: myFile rename base: 'temp'. – myFile itself is untouched, the renaming mode flag is set in the myFile copy that performs #base:
File Stat

All of the typical stat information about files and directories is directly obtainable from a Rio.
        • myFile fileSize
        • myFile modificationTime returns a DateAndTime
        • myFile creationTime returns a DateAndTime
        • myFile isFile
        • myFile exists
        • myFile isDirectory
Directory Queries #select:ing

Internally the operating system provides the above stat data on entries of the parent directory. Rio implements many of its features by using one single function #select:. When #select: is performed upon a directory it traverses all of the directory entries collecting stat data. We can make use of this to perform a wide variety of directory queries.
Given myDir := Cwd / 'package-cache':
        • myDir files => is implemented by: myDir select: [ :stat | stat isFile ]
        • myDir directories => is implemented by: myDir select: [ :stat | stat isDirectory ]
        • myDir entries => is implemented by: myDir select: [ :stat | true ]
        • Roll your own: files modified in 2007
                • myDir select: [ :stat | stat isFile & (stat modificationTime > '1-1-2007' asDate) ]
        • And the rather useful: myDir filesMatching: #('*.image' '*.changes')
Directory Queries On Steroids aka. 'Recursive' Mode

Having explained how the world of directories, their entries and stats revolves around #select:, now is the time to announce one other little feature of #select: - it can perform its search recursively. All of the above queries become full tree searches with the addition of one little word: #recursively or #all (they are equivalent).
        • myDir all files
        • myDir all directories
        • myDir all entries
        • Rolling your own: files modified in 2007
                • myDir recursively select:[ :stat | stat isFile & (stat modificationTime > '1-1-2007' asDate) ]
        • And the even more useful: myDir all filesMatching: #('*.image' '*.changes')
Essential Directory Operations

        • myDir mkdir - make a directory, raise an error if it already exists.
        • myDir rmdir - remove a directory if it exists and is empty, otherwise raise an error.
        • myDir ifAbsent mkdir - assure the existence of a directory
        • myDir ifAbsent mkpath - assure the existence of a directory and its parents.
        • myDir all delete mkpath - delete the old contents and make me a fresh temporary directory.(useful for temp directories)
Reading and Writing Files - No Forcing

Obtaining a stream for reading and writing files without forcing a new file is as simple as this:
        • To Obtain a readStream: readStream := 'myFile.txt' asRio reader.
        • To Obtain a writeStream: writeStream := 'myFile.txt. asRio writer.
        • Lazy method for obtaining file contents: 'myFile.txt' asRio reader contents.
        • Methods/usage idiom, which ensures that streams are correctly closed
                • for writing: 'myFile.txt' asRio writer out: [ :writeStream | ... ].
                • for writing: 'myFile.txt' asRio writer: [ :writeStream | ... ]. - abbreviated form
                • for reading: 'myFile.dat' asRio binary reader in: [ :readStream | ... ].
                • for reading: 'myFile.dat' asRio binary reader: [ :readStream | ... ]. - abbreviated form
        • Convenience method for creating an empty file - 'empty' asRio touch.
Reading and Writing - With Force.

One small modification to the above provides the equivalent of all of the #forceNewFileNamed: calls of old. (#assureNewFile is a synonym for #delete, but communicates different intent)
        • To 'forcefully' obtain a writeStream on a new file: 'myFile.txt' asRio assureNewFile writer
        • 'Forcefully' writing: 'myFile.txt' asRio assureNewFile writer: [ :writeStream | ... ]
Copying Files - Introducing 'Binary' Mode

The basic file copying feature is implemented by a generic stream to stream copying function aPositionableStream-#copyTo:. The aim here being to eliminate many places where this, "copy from one stream to another stream via a buffer", code is duplicated. (e.g. GZReadStream-#saveContents:, GZWriteStream-compressFile: etc.) aPositionableStream-#copyTo: honours the setting of #binary mode on the input stream being copied. To make use of this Rio itself has a 'binary' mode of its own which is passed on to the streams that it uses for reading, writing and copying files.
        • 'myFile.txt' asRio copyTo: 'yourFile.txt'
        • 'myFile.gz' asRio binary copyTo: 'yourFile.txt.gz'
Copying Files with Compression - Introducing Adaptors and 'GZip' Mode

'GZip' mode introduces a new Rio concept, Adaptors.

An adaptor is an additional protocol which is added to Rio as needed for a given mode. 'GZip' mode adds an adaptor that wraps the standard file readStream, and writeStreams with GZipReadStream, and GZipWriteStream respectively. Readers and writers can now be created directly onto compressed streams via the same API (note the binary setting is also honoured by compressed streams). This has additional benefits since, with the generic #copyTo: scheme (described above) in place, the act of (de)compressing files now becomes:
        • compressing a file: myFile binary copyTo: (MyFile + '.gz') gzip.
        • decompressing a file: (myFile + '.gz') binary gzip copyTo: myFile
        • reading a gzip file: 'myFile.txt.gz' asRio gzip reader contents
The GZip adaptor also adds some convenience methods to Rio as part of its protocol enabling the following:
        • compressing a file: 'myFile.dat' asRio gzip compress => 'myFile.dat.gz'
        • decompressing a file: 'myFile.dat.gz' asRio gzip decompress => 'myFile.dat'
Adding Files to an Existing Directory - The 'Dir' Adaptor

The 'Dir' Adaptor adds facilities for adding files, collections of files, or whole directory trees, into an existing directory.
        • copy a single file into a directory: myDirRio add: myFile.
        • copy a collection of files into a directory (flat):
                • myDirRio addAll: (myImagesDir all filesMatching: #('*.image' '*.changes'))
        • copy a whole directory tree into a directory: myDirRio addTree: yourDirRio.
        • copy selected files from a directory tree into a directory preserving the heirarchy
                • myDirRio addAll: (myImagesDir all filesMatching: #('*.image' '*.changes')) fromBase: myImagesDir.
Adding Files to Archives - The 'Archive' Adaptor.

The 'Archive' Adaptor is a specialisation of the 'Dir' adaptor, providing the exact same interface for copying files, selections of files, and directory trees into an archive file. Selecting #zip mode, sets the 'Archive' adaptor to generate a zip archive file. The zip file is not actually written until explicitly requested via a call to #commit, or the block form #commit:
        • copy a single file into a zip archive: 'my.zip' asRio zip add: myFile; commit.
        • copy a collection of files into a zip archive, without preserving heirarchy, i.e. flat.:
                • 'my.zip' asRio zip commit: [ :zip | zip addAll: (myImagesDir all filesMatching: #('*.image' '*.changes')) ]
        • copy a whole directory tree into an archive: 'my.zip' asRio zip addTree: yourDirRio; commit.
        • copy selected files from a directory tree into a zip archive preserving the heirarchy
                • 'my.zip' asRio zip commit: [ :zip | zip addAll: (myImagesDir all filesMatching: #('*.image' '*.changes')) fromBase: myImagesDir ]
Rio at Large

Rio's may be compared for equality with other Rio's, or directly with Strings. Rios may be used in many situations where you would use Strings. For example, a Rio may be included directly in a String concatentation. Rio's may be passed into, and obtained from the #name attribute of a StandardFileStream. To help with legacy integration, Rio's may also be passed in to many of FileDirectory's standard public methods.
_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project