Since the version 5, Pharo provides a new file streams API that makes the old one based on classes
like FileStream
or MultiByteBinaryOrTextStream
deprecated. Pharo 7 makes the next important
steps and removes usages of the old API from the kernel.
- use file references as entry points to file streams
- do not use
FileStream
class 'file.txt' asFileReference readStream
and similar methods now return an instance ofZnCharacterReadStream
instead ofMultiByteFileStream
'file.txt' asFileReference writeStream
and similar methods now return an instance ofZnCharacterWriteStream
instead ofMultiByteFileStream
- the new API has more clear separation between binary and text files
In this section, we will present the most common examples of file stream usages. For simplicity, errors are not handled.
FileStream forceNewFileNamed: '1.txt' do: [ :stream | stream nextPutAll: 'a ≠ b' ].
'1.txt' asFileReference ensureDelete;
writeStreamDo: [ :stream | stream nextPutAll: 'a ≠ b' ].
FileStream readOnlyFileNamed: '1.txt' do: [ :stream |
stream upToEnd ].
'1.txt' asFileReference readStreamDo: [ :stream |
stream upToEnd ].
(FileStream readOnlyFileNamed: '1.txt') contentsOfEntireFile.
'1.txt' asFileReference readStream upToEnd.
(FileStream forceNewFileNamed: '1.bin')
binary;
nextPutAll: #[1 2 3].
'1.bin' asFileReference ensureDelete;
binaryWriteStreamDo: [ :stream | stream nextPutAll: #[1 2 3] ].
(FileStream readOnlyFileNamed: '1.bin') binary; contentsOfEntireFile.
'1.bin' asFileReference binaryReadStream upToEnd.
FileStream forceNewFileNamed: '2.txt' do: [ :stream |
stream converter: (TextConverter newForEncoding: 'cp-1250').
stream nextPutAll: 'Příliš žluťoučký kůň úpěl ďábelské ódy.' ].
('2.txt' asFileReference) ensureDelete;
writeStreamEncoded: 'cp-1250' do: [ :stream |
stream nextPutAll: 'Příliš žluťoučký kůň úpěl ďábelské ódy.' ].
FileStream readOnlyFileNamed: '2.txt' do: [ :stream |
stream converter: (TextConverter newForEncoding: 'cp-1250').
stream upToEnd ].
('2.txt' asFileReference)
readStreamEncoded: 'cp-1250' do: [ :stream |
stream upToEnd ].
FileStream stdout nextPutAll: 'a ≠ b'; lf.
(ZnCharacterWriteStream on: Stdio stdout)
nextPutAll: 'a ≠ b'; lf;
flush.
FileStream stdout
converter: (TextConverter newForEncoding: 'cp-1250');
nextPutAll: 'Příliš žluťoučký kůň úpěl ďábelské ódy.'; lf.
(ZnCharacterWriteStream on: Stdio stdout encoding: 'cp1250')
nextPutAll: 'Příliš žluťoučký kůň úpěl ďábelské ódy.'; lf;
flush.
CAUTION: Following code will stop your VM until an input on STDIN will be provided!
FileStream stdin upTo: Character lf.
(ZnCharacterReadStream on: Stdio stdin) upTo: Character lf.
FileStream stdout
binary
nextPutAll: #[80 104 97 114 111 10 ].
Stdio stdout
nextPutAll: #[80 104 97 114 111 10 ].
CAUTION: Following code will stop your VM until an input on STDIN will be provided!
FileStream stdin binary upTo: 10.
Stdio stdin upTo: 10.
The message #position:
always works on the binary level, not on the character level.
'1.txt' asFileReference readStreamDo: [ :stream |
stream position: 4.
stream upToEnd ].
This will lead to an error (ZnInvalidUTF8: Illegal leading byte for utf-8 encoding) in case of the file created above because we set the position into the middle of a UTF-8 encoded character. To be safe, you need to read the file from the beginning.
'1.txt' asFileReference readStreamDo: [ :stream |
3 timesRepeat: [ stream next ].
stream upToEnd.].
The MultiByteFileStream
was buffered. If you create a stream using the expression
'file.txt' asFileReference readStream.
then the ZnCharacterReadStream
is not created directly on top of the stream but on top of a buffered stream
that uses the file stream internally.
If you will create a ZnCharacterReadStream
directly on the file stream, then the characters from the file are read
one by one which may be about ten times slower!
ZnCharacterReadStream on: (File openForReadFileNamed: 'file.txt').