我想将一个对象(一个简单的集合)写入一个文件。我一直在四处寻找this question和this question。我也经历了许多链接断开的网站,但我似乎无法找到一种方法来写入smalltalk中的文件。我试过这个(以及其他的东西,但它们都是相同的):
out := 'newFile' asFileName writeStream.
d associationsDo: [ :assoc | out
nextPutAll: assoc key asString;
nextPut: $, ;
nextPutAll: assoc value asString; cr. ]
out close.
如链接问题所示,但它似乎没有做任何事情。它不会抛出错误,但我也找不到任何文件。
我唯一想做的就是坚持我的对象(二进制或文本并不重要),所以我怎么能这样做?
提前致谢
答案 0 :(得分:4)
传统的Smalltalk序列化格式使用storeOn:
和readFrom:
方法。 E.g。
d1 := {'a'->1. 'b'->2. 'c'->'3'} as: Dictionary.
"store"
FileStream forceNewFileNamed: 'mydict.st' do: [:out | d1 storeOn: out].
"read"
d2 := FileStream oldFileNamed: 'mydict.st' do: [:in | Object readFrom: in].
这是一种文本格式,对于较大的数据集效率低下。此外,它不能存储周期性参考。为此,请查看其他答案中列出的更高级的序列化选项。
答案 1 :(得分:3)
您正在做的是在字符串上创建写入流。这实际上有效,但信息存储在字符串对象上,不会写入任何文件。
这适用于Squeak和Pharo(可能还有其他方言):
FileStream
forceNewFileNamed: 'filename.ext'
do: [ :stream |
d associationsDo: [ :assoc |
stream
ascii; "data is text, not binary"
nextPutAll: assoc key asString;
nextPut: $, ;
nextPutAll: assoc value asString;
cr ] ].
在Pharo你可以写:
'filename.ext' asFileReference writeStreamDo: [ :stream |
... ].
但请注意,有更好的方法可以在文件中存储结构化数据,例如STON(Smalltalk Object Notation,Smalltalk版本的JSON)或XML。如果要保留对象,则可能需要签出Fuel,StOMP(可能不再支持)或任何其他对象序列化程序。
最后还有ImageSegment,一个基于VM的对象序列化器(不需要额外的软件包),但是你可能需要一些帮助。
答案 2 :(得分:2)
解决方案:
| d out |
d := Dictionary new.
d at: 'green' put: 'vert'.
d at: 'blue' put: 'bleu'.
d at: 'red' put: 'rouge'.
d at: 'white' put: 'blanc'.
out := FileStream fileNamed: 'dict-out.txt'.
d associationsDo: [ :assoc | out
nextPutAll: assoc key asString;
nextPut: $, ;
nextPutAll: assoc value asString; cr.].
out close.
另见:
答案 3 :(得分:1)
您似乎正在使用扩展的语法,但不是基础。
至少在Pharo中,'newFile' asFileName
是一个字符串,#writeStream为您提供相同字符串的流,而不是文件。
尝试使用FileStream newFileNamed: 'newFile'
或类似的东西。
最重要的是:当发生奇怪的事情时,请检查。检查部分评估并检查所有假设。或者更好的是,调试并查看代码的去向。
答案 4 :(得分:1)
燃料中的等价物将是
FLSerializer serialize: d toFileNamed: 'filename.ext'.
和
d := FLMaterializer materializeFromFileNamed: 'filename.ext'