如何将read/write对象写入文件?
How to read/write objects to a file?
我想将一个对象(一个简单的集合)写入一个文件。我一直在四处寻找并找到 this question and this question。我还浏览了很多链接断开等的站点,但我似乎无法找到在 smalltalk 中写入文件的方法。我试过这个(和其他东西,但它们归结为相同):
out := 'newFile' asFileName writeStream.
d associationsDo: [ :assoc | out
nextPutAll: assoc key asString;
nextPut: $, ;
nextPutAll: assoc value asString; cr. ]
out close.
如链接问题中所建议的那样,但它似乎没有做任何事情。它不会抛出错误,但我也找不到任何文件。
我唯一想做的就是保留我的对象(二进制或文本并不重要),那么我该怎么做呢?
提前致谢
看来您使用的是扩展语法,而不是基础语法。
至少在 Pharo 中,'newFile' asFileName
是一个字符串,而#writeStream 为您提供了同一字符串上的流,而不是文件上的流。
试试 FileStream newFileNamed: 'newFile'
或类似的东西。
最重要的是:当发生奇怪的事情时,请检查。检查部分评估并检查您的所有假设。或者更好的是,调试并查看代码的去向。
您正在做的是在字符串上创建写入流。这确实有效,但信息存储在字符串对象中,不会写入任何文件。
这适用于 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 version of JSON) or XML. If you want to persist objects than you might want to checkout Fuel, StOMP(可能不再受支持)或任何其他对象序列化程序。
最后还有 ImageSegment,一个基于 VM 的对象序列化程序(不需要额外的包),但您可能需要一些帮助。
解决方案:
| 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.
另请参阅:
传统的Smalltalk序列化格式使用storeOn:
和readFrom:
方法。例如
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].
这是一种文本格式,对于较大的数据集来说效率很低。此外,它不能存储循环引用。为此,请查看其他答案中列出的更高级的序列化选项。
燃料中的等价物是
FLSerializer serialize: d toFileNamed: 'filename.ext'.
和
d := FLMaterializer materializeFromFileNamed: 'filename.ext'
我想将一个对象(一个简单的集合)写入一个文件。我一直在四处寻找并找到 this question and this question。我还浏览了很多链接断开等的站点,但我似乎无法找到在 smalltalk 中写入文件的方法。我试过这个(和其他东西,但它们归结为相同):
out := 'newFile' asFileName writeStream.
d associationsDo: [ :assoc | out
nextPutAll: assoc key asString;
nextPut: $, ;
nextPutAll: assoc value asString; cr. ]
out close.
如链接问题中所建议的那样,但它似乎没有做任何事情。它不会抛出错误,但我也找不到任何文件。
我唯一想做的就是保留我的对象(二进制或文本并不重要),那么我该怎么做呢?
提前致谢
看来您使用的是扩展语法,而不是基础语法。
至少在 Pharo 中,'newFile' asFileName
是一个字符串,而#writeStream 为您提供了同一字符串上的流,而不是文件上的流。
试试 FileStream newFileNamed: 'newFile'
或类似的东西。
最重要的是:当发生奇怪的事情时,请检查。检查部分评估并检查您的所有假设。或者更好的是,调试并查看代码的去向。
您正在做的是在字符串上创建写入流。这确实有效,但信息存储在字符串对象中,不会写入任何文件。
这适用于 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 version of JSON) or XML. If you want to persist objects than you might want to checkout Fuel, StOMP(可能不再受支持)或任何其他对象序列化程序。
最后还有 ImageSegment,一个基于 VM 的对象序列化程序(不需要额外的包),但您可能需要一些帮助。
解决方案:
| 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.
另请参阅:
传统的Smalltalk序列化格式使用storeOn:
和readFrom:
方法。例如
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].
这是一种文本格式,对于较大的数据集来说效率很低。此外,它不能存储循环引用。为此,请查看其他答案中列出的更高级的序列化选项。
燃料中的等价物是
FLSerializer serialize: d toFileNamed: 'filename.ext'.
和
d := FLMaterializer materializeFromFileNamed: 'filename.ext'