2016-01-11 4 views
4

Я хотел бы написать объект (простую коллекцию) в файл. Я искал и нашел 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. 

как предложено в связанных вопросов, но это, кажется, не делать ничего. Это не вызывает ошибок, но я тоже не нахожу файлы.

Единственное, что я хочу сделать, это сохранить мой объект (двоичный или текстовый не имеет значения), так как я могу это сделать?

Заранее спасибо

ответ

3

Что вы делаете, это создание потока записи в строке. Это действительно работает, но информация хранится в строковом объекте, файлы не будут записаны.

Это работает в обоих писк и 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, объект-сериализатор на основе виртуальной машины (без дополнительных пакетов), но вам, вероятно, понадобится помощь в этом.

+1

Stomp, кажется, не больше не поддерживается. Последние выпуски для Pharo 1.2 и Squeak 4.2. – Kwaku

+0

Спасибо. И все же оставим ссылку на документацию. –

+0

И STON только для Pharo. Топливо не позволяет передавать объекты с Фаро на Писк. Примечательно, что SIXX http://www.mars.dti.ne.jp/~umejava/smalltalk/sixx/index.html – Kwaku

1

кажется, что вы используете синтаксис для расширения, но не основание. По крайней мере, в Pharo, 'newFile' asFileName - это строка, а #writeStream предоставляет поток в одной строке, а не в файле.

Попробуйте с FileStream newFileNamed: 'newFile' или что-нибудь в этом духе.

И больше всего: когда что-то странное происходит, осмотрите. Осмотрите частичные оценки и проверьте все свои предположения. Или еще лучше, отлаживать и видеть, где находится код.

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. 

Смотрите также:

4

Традиционный формат 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]. 

Это текстовый формат и неэффективен для больших наборов данных. Кроме того, он не может хранить циклические ссылки. Для этого ознакомьтесь с более расширенными параметрами сериализации, указанными в других ответах.

1

Эквивалент в топливе будет

FLSerializer serialize: d toFileNamed: 'filename.ext'. 

И

d := FLMaterializer materializeFromFileNamed: 'filename.ext'