Hello,
Note that the question has also been cross-posted to Stack Overflow: https://stackoverflow.com/questions/77360448/pharo-or-squeak-how-to-get-a-li...
The accepted answer there is for the FileSystem programming interface that is also available for Squeak, but not out of the box, contrary to Pharo. FileSystem has a convenient allChildren message that answers a collection with all the recursive subdirectories and files.
In Squeak, without loading any additional extensions, we only have the FileDirectory programming interface. It has similar messages, but apparently none as straightforward as allChildren.
For example, there is a message called withAllSubdirectoriesCollect:, which evaluates a code block for every directory in the tree, and from the directory you can get all the contained files.
(UIManager default chooseDirectory: 'Select directory of the collection' from: FileDirectory default) "This will result in a FileDirectory object unless you cancel the dialog." withAllSubdirectoriesCollect: [:eachDirectory | "eachDirectory is a FileDirectory object." eachDirectory fileEntries do: "This loops through all the files (not subdirectories) in eachDirectory." [:eachFileEntry | "eachFileEntry is a DirectoryEntry object." Transcript show: eachFileEntry fullName; cr]]
Please look up the FileDirectory and DirectoryEntry classes in Squeak to find out what you can do with them, and ask any further questions that you might have.
Instead of writing the file names to the transcript, you could also put the directory entries into a collection of yours, or first convert them to Cards and add them to your library directly.
There is another message that also includes all the files in the traversal directly, not only directories (so you do not need two nested blocks of code), but it seems a bit awkward to me: it is called directoryTreeDo: and it evaluates a code block for each file and directory. As an argument to this code block, it provides a list of the DirectoryEntries that lead to this file or directory... From the user perspective, that is a rather convoluted way to pass the path to the file or directory, in my opinion. But if you just look at the last entry of the provided list, you should be able to get all that you need for each file.
Here is an example:
(UIManager default chooseDirectory: 'Select directory of the collection' from: FileDirectory default) directoryTreeDo: [:each | Transcript show: each last fullName; cr]
`each last` in the block is the DirectoryEntry for the current file or directory. For example, you can seek out only the files by testing with `each last isFile`
... directoryTreeDo: [:each | each last isFile ifTrue: [Transcript show: each last fullName; cr]]
Kind regards, Jakob
Am Do., 26. Okt. 2023 um 03:57 Uhr schrieb lewis@mail.msen.com:
Hi,
This is a very good question.
I do not have a good answer, but I am replying here with CC to the squeak-dev list because I would like to get a response to this question.
In my own personal experience, when I want to traverse the files and directories, I am in the habit of just using the traditional unix 'find' utility because it does a very good job of this, and it knows how to handle file system dependencies such as links and symlinks. I can use the results of the 'find' command in Squeak, so that works well for me.
But if I want to traverse a file system tree directly in Squeak, is there a good simple way to do it? Presumably one would want to visit each node in the tree and evaluate a block to do something. In the example below, we would want the block to create an instance of class Card for each file node that is visited.
For folks replying on squeak-dev please keep in mind that the question originates from the beginners list, so we are looking for a clear and simple answer :-)
Thanks, Dave
On 2023-10-24 18:27, ruivianapereira@gmail.com wrote:
I'm not a programmer of any kind or language; I'm an amateur. I have a personal digital library with thousands of documents, which are useless unless I manage to classify them. I thought it would be an easy task with Squeak, since it is a quite simple problem, but I'm lacking some solutions, as a beginner. My general cenario: I made a class, lets call it card, to hold information about each work, each author, their location on disk and the relations between authors and works: Object>>#Card (instance var : name, location, notes, tags ... ) Author Work
Object>>#MyLibrary (instance var : authors <aCollection>, works <aCollection>, myLibraryBase <aPath?>)
Than I initialize #MyLibrary instances with a UIManager directoryChooser to establish from the begining a reference to the directory where all the relevant files are. But, because it is thousands of files, I would need an automatic method to «scan» all the relevant files in the directories and subdirectories. Meaning: the method should make a collection of all the files, recursively in subdirectories, and for each one it should create a card. And that's where I got stuck: how do I scan recursively the subdirectories? Most of the new tools are quite confusing for me, namely classes and tools to deal with files.
Can anyone point me in the wright direction, please? Thanks _______________________________________________ Beginners mailing list -- beginners@lists.squeakfoundation.org To unsubscribe send an email to beginners-leave@lists.squeakfoundation.org