2. What is FileMan?
Handy class libraries for handling files and
directories in Smalltalk
Small
Easy to use
Portable (Squeak and VisualWorks)
Extensible
3. File handling in Squeak
We can use existing class libraries
FileStream, FileDirectory, FilePath, etc
Why FileMan?
I feel frustrated...
○ Not well designed in OO way...
○ Need to write many codes...
○ I can imagine a simpler way...
=> Decided to start FileMan
4. How to get FileMan
Squeak
SqueakMap (Stable)
○ http://map.squeak.org/package/f9917683-25da-
4a6c-a013-b36527a100c1
SqueakSourceJ (Current)
○ http://squeaksource.blueplane.jp/FileMan.html
VisualWorks
Cincom Public Store Repository
5. Sample code
Create ’subDir’ directory under the current
directory, and make a text file named ’ file1.txt’
whose contents are ’Hello!’
Normal
FileMan
subDir := FileDirectory default directoryNamed: 'subDir'.
subDir assureExistence.
[str := subDir newFileNamed: 'file1.txt'.
str nextPutAll: 'Hello!']
ensure: [str close].
'./subDir' asDirectoryEntry at: 'file1.txt' put: 'Hello!'
6. FileMan’s strong point (1)
Small
Only three core classes
○ FmFileEntry
represents file
○ FmDirectoryEntry
represents directory
○ FmFileIOAccessor
adapter for File I/O
(You are not aware of it except for porting
FileMan)
7. FileMan’s strong point(2)
Easy to use
All objects: Files and Directories
○ To File: Modification time? Size? Contents?
○ To Directory: Children files? Directories?
just ask them!
Dictionary-like API for Directory
○ key: file name, value: contents
○ For reading #at:, For writing: #at:put:
8. FileMan’s strong point(3)
Portable
Path representation is independent of platforms
○ ‘.¥subDir¥subSubDir’ asDirectoryEntry
is portable because
runs on Win, Mac, Linux with no changes
- FileMan absorbs separator’s differences
○ ‘/tmp’ asDirectoryEntry at: ‘myData’ put: data
is also portable
- runs on all platforms
- FileMan also attaches a ‘drive letter’ if necessary
9. FileMan’s strong point(4)
Extensible
By overriding FmDirectoryEntry, FmFileEntry
respectively, you can attach special behaviors
transparently
Example: auto compress/uncompress
○ In #at:put:, a file ’text.gz’ will be created automatically
○ In #at:, ’text.gz’ will be uncompressed
| dir |
dir := './gzipped' asDirectoryEntry: FmGZipDirectoryEntry.
dir at: ‘text’ put: ‘I will be compressed'.
(dir at: 'text') inspect.
10. Example (1)
Backup
Backup all files under ‘foo’ directory into
‘bkUp’ subdirectories everyday
'./foo' asDirectoryEntry copyTo: './bkUp' / Date today yyyymmdd
11. Example (2)
Error log
Append error information to ‘error.log’ file
‘error.log’ asFileEntry appendContents: ‘Error...’
12. Example (3)
Clean-up of dated files
Clean up all ‘.txt’ extension files under ‘foo’ directory
that have not been updated for 100 days
dir := './foo' asDirectoryEntry.
current := TimeStamp current .
dir allFilesDo: [:file |
((file extension = 'txt') &
((TimeStamp fromSeconds: file modificationTime) plusDays: 100)< current)
ifTrue: [file delete]
].
13. Example (4)
Text file conversion
Convert all UTF-8, CR line-end text files
into Shift-JIS, CRLF line-end files
conv := [:in :out |
out wantsLineEndConversion: true; lineEndConvention: #crlf;
converter: ShiftJISTextConverter new.
out nextPutAll: (in upToEnd)
].
dir := './foo' asDirectoryEntry.
dir filesDo: [:file |
file pipe: conv to: (dir / (file name copyReplaceAll: '.txt' with: '.sjis.txt'))
]
14. Summary
FileMan makes your program simple:
powerful, simple classes for handling files and
directories
Please use FileMan for daily tasks