要約: | - ストリームとは、リソースに対する読み取りまたは書き込みが可能なデータ列です。
- ストリームは単一方向です。
|
ストリームは、アプレットで読み取りまたは書き込みのいずれかか可能なデータ列です。リソースとデータを交換するための汎用インタフェースを生成します。通常は、ストリームを作成したらその出力先を気にする必要はありません。
ストリームは一方向にのみ流れます。プログラムは、入力ストリームからデータを読み取り、出力ストリームにデータを書き込みます。読み取りと書き込みの両方を行うリソースの場合 (たとえばネットワーク ソケットなど) は、そのリソースに対する入力および出力ストリームの両方を開く必要があります。
要約: | - ストリームは、その特徴によって分類されます。
- 入力ストリームからはデータを読み取り、出力ストリームにはデータを書き込みます。
- バイナリ ストリームは生バイトを扱い、テキスト ストリームはテキストを扱います。
- バッファ ストリームは、バッファを使用してオーバーヘッドを削減します。
|
ストリーム クラスにはさまざまなものがあります。これらのクラスの相違点は、その機能や目的によるものです。
次に相違点を示します。
- ストリームは、入力ストリームまたは出力ストリームのいずれかです。入力ストリームからはデータを読み取り、出力ストリームにはデータを書き込みます。
- ストリームは、さまざまなタイプのデータを扱います。テキスト ストリームは、文字で構成されたデータを扱います。バイナリ ストリームは、生バイトのデータを扱います。トランスコード ストリームは、1 バイトより大きいデータを使ってエンコードされたテキスト (Unicode テキストなど) を読み取ります。テキストおよびトランスコード ストリームの詳細は、「テキスト ファイルの読み取りと書き込み」セクションを参照してください。
- ストリームは、バッファに格納されるまたは格納されないのいずれかのタイプになります。バッファストリームでは、データは一時的にバッファに格納されます。バッファ入力ストリームは、バッファに格納可能な量のデータを読み取り、データを読み取るプログラムに渡します。バッファ出力ストリームは、バッファがいっぱいになるまでリソースに書き込まれるデータをバッファに格納してから、実際にリソースに書き込みます。バッファにより、リソース (ネットワーク上のホストやディスクなど) へのアクセスに必要なオーバーヘッドを削減できます。
- ストリームは、シーク可能またはシーク不可能にすることができます。シーク不可能のストリームでは、データの読み取りまたは書き込みは 1 か所のみに限られます。ストリームがシーク可能な場合、ストリーム内のデータの読み取りまたは書き込みを行う位置を変更できます。
要約: | - バイナリ ファイルの読み取りおよび書き込みには、バイト ストリームを使用します。
- read-open-byte は、生バイナリ データとしてファイルを開きます。
- データを格納するには byte 型のオブジェクトを使用します。
- read および read-one はバイナリ データを読み取ります。
- read-bytes-from は、1 度のステップでファイルを開いて読み取ります。
- バイナリ ファイルの書き込みは、テキスト ファイルの書き込みと似ています。
|
バイト ストリームにより、生バイナリ データの読み取りと書き込みが可能になります。Curl® 実行環境 ではデータの解釈は行なわれません。これらのストリームは、主に低レベルでバイナリ データ (イメージ ファイルなど) を操作する必要がある時に使用します。通常は、規定のバイト ブロック単位でこれらのストリームの 1 つに対して読み取りおよび書き込みを行います。
バイナリ ストリームからの読み取りは、1 つの例外を除けばテキスト ストリームからの読み取りと似ています。
byte として宣言されたオブジェクトに値を読み込む必要があります。Curl® 言語の文字は 1 バイトより大きく、Unicode 文字表記が可能なため、
char として宣言されたオブジェクトを使用できません。
次の例では、byte 配列にバイナリ ファイル (ユーザー提供のイメージ ファイル) が読み込まれることを示しています。read メソッドが使用されています。通常このメソッドでは、1 度の呼び出しでファイル全体を配列に読み込むことになります。
例:
byte 配列にバイナリ ファイルを読み込む |
 |
|| Get an input stream from a Url, read data into an array of bytes
|| report the number of bytes read.
{let results:TextFlowBox = {TextFlowBox}}
{let image-file-types:{Array-of FileDialogFilter} =
{new
{Array-of FileDialogFilter},
{FileDialogFilter
"Image files",
{new
{Array-of FileDialogTypeFilter},
{FileDialogTypeFilter "bmp"},
{FileDialogTypeFilter "jpg"},
{FileDialogTypeFilter "jpeg"},
{FileDialogTypeFilter "gif"},
{FileDialogTypeFilter "png"}
}
}
}
}
{paragraph
Click the button below to choose an image file from
your system. If you do not have one handy, there is
a {monospace .gif} file located at {value
{url "../../default/images/url-accessor-diagram.gif"}.name}
}
{VBox
{CommandButton
label="Choose an Image File",
{on Action do
{results.clear}
let file-url:#Url = {choose-file filters=image-file-types}
{if-non-null file-url then
let my-input:#ByteInputStream
{try
|| Open the file
set my-input = {read-open-byte file-url}
|| Read from the file. This usually will return the
|| entire content of the file, if you are reading
|| from the local file system.
let (buffer:#{Array-of byte}, count:int) = {my-input.read}
{results.add
{text Got {value count} bytes of data from the file.}
}
catch err:IOException do
{results.add
{text Error occurred while reading the file:
{italic {value err.value}}
}
}
finally {if-non-null my-input then {my-input.close}}
}
}
}
},
results
}
| |
ファイルへのバイトの書き込みは、テキスト ファイルへの書き込みと似ています。ファイルにバイトを書き込むには、次を実行します。
- write-open-byte を使用して、書き込み用のファイルを開きます。
- write または write-one メソッドを使用してファイルにデータを書き込みます。
- リソースにすべてのデータが書き込まれたことを確認するには、flush メソッドを使用します。
- close メソッドを使用してファイルを閉じます。
注意: 書き込まれたファイルは、必ず適切に閉じてください。適切に閉じられていないと、データが失われる可能性があります。
要約: | - 既定ではすべてのストリームがバッファに格納されます。
- ほとんどの場合、ファイルを開くプロシージャでバッファ サイズを指定できます。
- バイト ストリームをバッファに格納することを望まない場合もあります。
|
バッファ ストリームでは、リソースに対して読み取りおよび書き込みが行なわれるデータがメモリ内の一時バッファに格納されます。リソースへのアクセスによるオーバーヘッド (ディスクへのアクセス待機やネットワーク上のホスト待機など) が大きくなる場合が多いため、バッファを使用してプログラムを効率的に実行します。
既定では、ファイルを開くための通常のプロシージャ (
read-open や
write-open-byte など) はすべてバッファ ストリームを返します。これらのすべてのメソッドは、ストリーム上で使用されるバッファ サイズを微調整するための
buffer-size パラメータをオプションとして持っています。バッファ サイズはデータ量やデータを書き込む頻度に応じて選択できます。
多量のデータの読み取りまたは書き込みでは、バッファを使用するとリソースに直接書き込むより経費がかかる場合があります。この場合、バッファ サイズをゼロに設定してバイト ストリーム上のバッファを削除できます。
要約: | - シーク可能ストリームでは、ストリームの任意の位置にアクセスできます。
- すべてのストリームがシーク可能ではありません。
- ストリームがシーク可能かどうか判別するには isa Seekable を使用します。
- 対応する Seekable にストリームをキャストする必要があります。
|
既定のストリーム クラスでは、ストリーム内の現在の位置でのみ読み取りまたは書き込みが可能です。たとえば、通常の入力ストリームでは先頭から読み始め、最後まで継続することしかできません。
シーク可能ストリームでは、ストリーム内の異なる位置で読み取りまたは書き込みができます。シーク可能ストリームを使用すると、ファイルからデータを抽出したり、ファイル内の特定の位置にデータを格納する必要があるようなファイルを構築できます。
シーク可能にできるのは、不連続にアクセスできるリソース対して出入力するストリームに限られます。ローカル ファイル システムのファイルは、内容全体を一度でアクセスできるのでシーク可能です。ソケットやファイルから HTTP やソケットを介して読み取るストリームは、最初から最後まで直線的に読み取るしかできないのでシーク可能ではありません。
ストリームがシーク可能かどうかを判断するには、次のように
Seekable かどうかをテストします。
{if my-stream isa Seekable then
|| ... use the stream as a seekable
}
このテストに成功すれば、ストリームをシーク可能ストリームの適切なクラス (
SeekableTextInputStream など) にキャストできます。使用可能なシーク可能クラスの一覧については、『API リファレンス マニュアル』で
「シーク可能」を参照してください。
要約: | - seek によりストリーム内を移動できます。
- seek-style-supported? では、特定の位置を基準にして移動できることを確認します。
|
offset パラメータは、ストリーム内で移動する距離を表します。
from パラメータは
SeekFrom 列挙型のメンバで、
offset の基準となるストリーム内の位置を示します。
seek がサポートする位置の一覧については、『API リファレンス マニュアル』の
SeekFrom エントリを参照してください。
ストリーム内の任意の位置にシークする前に、その位置からのシークをストリームがサポートしているかどうかを確認します。ストリームが
SeekFrom に示されるすべての位置からのシークをサポートしていない場合があります。
Seekable.seek-style-supported? メソッドを使用すると、ストリームが該当する位置からシーク可能かどうかを確認できます。
このメソッドでは、パラメータとして
SeekStyle 列挙型のメンバが必要です。この列挙では可能な組み合わせが多いため、
SeekFrom の列挙とは異なります。
style の値の一覧については、『API リファレンス マニュアル』の
SeekStyle エントリを参照してください。
次の例では、ストリームがシーク可能かどうかを判断し、シーク可能な場合にシーク可能メソッドを使用してストリーム内を移動する方法を示します。
注意: この例は、読み込み操作で character-encoding = "shift-jis" を使用します。
ユーザーが選択したファイルがこの文字エンコーディングと互換性がない場合は、エラーがスローされます。
例:
シーク可能ストリームの使用 |
 |
|| Demonstrate using a seekable stream.
{let results:VBox = {VBox}}
{let text-file-types:{Array-of FileDialogFilter} =
{new
{Array-of FileDialogFilter},
{FileDialogFilter
"Text files",
{new
{Array-of FileDialogTypeFilter},
{FileDialogTypeFilter "txt"},
{FileDialogTypeFilter "curl"}
}}}}
{CommandButton
label="Select a Text File",
{on Action do
let file-url:#Url = {choose-file filters=text-file-types}
{results.clear}
{if-non-null file-url then
let my-input:#TextInputStream
{try
|| Open the file
let my-input = {read-open
character-encoding = "shift-jis",
file-url}
let count:int = 0
|| See if the file is seekable.
{if my-input isa Seekable then
|| Get a reference to the file that is an appropriate seekable
||stream class.
let seek-input:SeekableTextInputStream =
(my-input asa SeekableTextInputStream)
|| Use the tell method to determine where we are in the stream
{results.add
{text Current position is {seek-input.tell}}
}
|| Ensure we can seek from the start of the stream.
{if {seek-input.seek-style-supported? "start"} then
|| Jump 20 characters into the stream.
{seek-input.seek 20, "start"}
|| Find out where we are now
{results.add
{text Now at {seek-input.tell}}
}
|| Read next 10 characters
let buffer:StringBuf =
{seek-input.read-one-string n=10}
{results.add
{text The next 10 characters in the
stream are: {quote {pre {value buffer}}}
}
}
{results.add
{text After reading, we're at
{seek-input.tell}}
}
}
|| See if it is safe to seek from the end of the stream
{if {seek-input.seek-style-supported? "end"} then
|| move 10 characters from the end of the stream. Note
|| that seeking from the end requires a negative offset.
{seek-input.seek -10, "end"}
|| Find out where we are now
{results.add
{text After moving to the last 10 characters,
we're at {seek-input.tell}}
}
|| Read next 10 characters
let buffer:StringBuf =
{seek-input.read-one-string n=10}
{results.add
{text The last 10 characters in the stream are:
{quote {pre {value buffer}}} (note that not all of
the characters read are printable).}
}
}
|| Again, make sure it's OK to move relative to
|| the start of the stream
{if {seek-input.seek-style-supported? "start"} then
|| Move back to the start
{seek-input.seek 0, "start"}
|| read the whole buffer into a StringBuf
let (buffer:StringBuf, numchars:int) =
{seek-input.read-one-string}
{results.add
{text The entire stream is:
{quote {pre {value buffer}}}
and is {value numchars} characters long.}}
}
}
catch err:IOException do
{results.add
{text An error occurred while accessing the file:
{italic {value err.value}}
}
}
finally
{if-non-null my-input then
{my-input.close}
}
}
}
}
}
{value results}
| |
Curl 実行環境 は、圧縮データ ストリームに対する読み取りおよび書き込みをサポートしています。この機能を使用すると、ディスクへ書き込むファイル サイズを小さくしたり、データを圧縮して遅いネットワーク リンク上でより経済的にデータを転送することができます。
圧縮ストリームで使用される圧縮アルゴリズムは、DEFLATE 圧縮データ形式です。詳細については、『RFC 1951 DEFLATE Compressed Data Format Specification version 1.3』を参照してください。
これらのクラスは
CURL.IO.ZSTREAM パッケージの一部で、実行時のコア パッケージには含まれていません。したがって、アプレットで圧縮ストリームの読み取りおよび書き込みを可能にするには、このパッケージをインポートする必要があります。パッケージのインポートの詳細は、「
import 式」を参照してください。
圧縮ファイルにデータを書き出すには、次を実行します。
次の例では、選択するファイルに
TextArea の圧縮データを書き込んだ後で、圧縮データを再度読み取ります。最初はデータが圧縮されたことを示すために通常のバイト ストリームとして、次に圧縮されたテキスト データを読み取るために圧縮ストリームを使用します。
例:
圧縮ストリームの読み取りと書き込み |
 |
|| Import the package containing the compressed streams
{import * from CURL.IO.ZSTREAM}
{let output-area:VBox = {VBox}}
{let my-text:TextArea = {TextArea
value="This is some text that the " &
"compressed stream will write. " &
"It repeats in order to make the text " &
"more compressible. " &
"This is some text that the " &
"compressed stream will write. " &
"It repeats in order to make the text " &
"more compressible. "
}
}
{VBox
width=5in,
my-text,
output-area,
{CommandButton
label="Choose & Write File",
{on Action do
{output-area.clear}
|| ask user for a file
let target:#Url = {choose-file
style=FileDialogStyle.save-as,
title="Demonstrate Compressed Streams"
}
{if-non-null target then
let output-stream:#TranscodingTextOutputStream
{try
|| Open the file for writing, connecting the output
|| stream to a compressed stream, then connecting the
|| compressed stream to a stream that will turn
|| ASCII text into bytes.
set output-stream = {TranscodingTextOutputStream
{DeflateByteOutputStream
{write-open-byte target}
},
CharEncoding.ascii,
true
}
|| Write the string.
let output-size:int =
{output-stream.write-one-string my-text.value}
{output-area.add
{text Wrote the string:
{italic {value my-text.value}}
which was {value output-size} characters
long.
}
}
catch e:IOException do
{output-area.add
{text color="red", An error occurred while
accessing the file: {italic {value e.value}}
}
}
finally
|| Close the topmost stream, which will flush &
|| close all of the underlying streams as well.
{if-non-null output-stream then
{output-stream.close}
}
}
{try
|| Read file back in to see how large it is
let (bytes:{Array-of byte}, read-size:int) =
{read-bytes-from (target asa Url)}
{output-area.add
{text The compressed file size is:
{value read-size}
}
}
catch e:IOException do
{output-area.add
{text color="red", An error occurred while
accessing the file: {italic {value e.value}}
}
}
}
|| Now let's read the file back in and decompress it.
let input-stream:#TranscodingTextInputStream
{try
set input-stream = {TranscodingTextInputStream
{InflateByteInputStream
{read-open-byte target}
},
character-encoding=CharEncoding.ascii
}
let (input-buf:{Array-of char}, in-count:int) = {input-stream.read}
{output-area.add
{text
Read {value in-count} characters back from the
compressed file.
}
}
catch err:IOException do
{output-area.add
{text color="red", Problem reading compressed file:
{value err.value}
}
}
finally
{if-non-null input-stream then
{input-stream.close}
}
}
}
}
}
}
| |
バージョン 6.0 の Curl API はシリアル化のインターフェースに対し、数々の拡張を提供します。以下のリストでは変更点を要約しています。
次の例では、11 個の整数をシリアル化してファイルに書き込み、その後 deserializeプリミティブを使用してそれらの値を読み取り、シリアル化を解除しています。
例:
整数のシリアル化 |
 |
{import * from CURL.IO.SERIALIZE}
{let stored-values:HBox = {HBox spacing = 5pt}}
{let read-ints:int}
{define-proc {save-and-restore target:Url}:void
{with-open-streams
out = {SerializeOutputStream {write-open-byte target}}
do
{for i:int=0 to 10 do
{out.write-one i}
}
}
{stored-values.clear}
{with-open-streams
in = {SerializeInputStream {read-open-byte target}}
do
{stored-values.add {TextFlowBox width = 3cm, "stored integers:"}}
{for i:int=0 to 10 do
set read-ints = {deserialize in, int}
{stored-values.add read-ints}
}
}
}
{VBox
{CommandButton
label="Select a File",
{on Action do
let target:#Url = {choose-file
style = FileDialogStyle.save-as,
title = "Demonstrate Serialization"
}
{if-non-null target then {save-and-restore target}}
}
},
stored-values
}
| |
次の例では、10 個の整数の配列をシリアル化し、その後シリアル化を解除しています。配列全体が 1 つのデータ オブジェクトとして処理されていることに注意してください。
例:
配列のシリアル化 |
 |
{import * from CURL.IO.SERIALIZE}
{let stored-values:HBox = {HBox spacing = 5pt}}
{let arr:{Array-of int} = {{Array-of int} 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}}
{let read-arr:{Array-of int} = {new {Array-of int}}}
{define-proc {save-and-restore target:Url}:void
{with-open-streams
out = {SerializeOutputStream {write-open-byte target}}
do
{out.write-one arr}
}
{stored-values.clear}
{with-open-streams
in = {SerializeInputStream {read-open-byte target}}
do
set read-arr = {deserialize in, {Array-of int}}
{stored-values.add {TextFlowBox width = 3cm, "stored array:"}}
{for x:int in read-arr do
{stored-values.add x}
}
}
}
{VBox
{CommandButton
label="Select a File",
{on Action do
let target:#Url = {choose-file
style = FileDialogStyle.save-as,
title = "Demonstrate Serialization"
}
{if-non-null target then {save-and-restore target}}
}
},
stored-values
}
| |
ユーザー独自のシリアル化可能なクラスを定義すると、複雑な Curl データの保存と復元が可能になります。シリアル化可能なクラスを示すには、serializable 修飾子を使用します。シリアル化可能なクラスは、すべてのシリアル化可能なスーパークラスと、transient 修飾子で一時的として示されていないすべてのフィールドを書き込んだり復元したりします。
シリアル化可能なクラスの定義にはいくつかの制限があります。
- あるクラスがシリアル化できないスーパークラスを継承している場合、そのクラスは明示的に object-deserialize コンストラクタを定義する必要があります。もしくは、シリアル化できない各スーパークラスは(シリアル化の解除の際に呼び出される)引数無しで呼び出されるコンストラクタを保有する必要があります。
- シリアル化できないスーパークラスを継承しているクラスで、かつ strict-serialization? コンパイラ ディレクティブ が true に設定されている場合、シリアル化できない各スーパークラスは、間接的に継承されたものも含めて、非 transient フィールドを保持することはできません。もしくは、そのクラスは明示的に object-serialize メソッドと object-deserialize コンストラクタの両方を定義する必要があります。上記の理由から、非 transient 状態のクラスがシリアル化可能なサブクラスを持つ場合は、そのクラスが serializable であると宣言することを推奨します。
- クラス修飾詞が shared で、(「クラス」の shared クラスについての説明を参照してください) かつ serializable クラスを直接継承している場合は、object-serialize と object-deserialize の両方を定義する必要があります。
object-serialize と
object-deserialize についての詳細は、以下および
CURL.IO.SERIALIZE パッケージのドキュメントを参照してください。
次のコード サンプルは、文字列 (name) と整数 (score) を含む単純なシリアル化可能クラスを示しています。最高得点者の名前と得点を保存するゲームのユース ケースをシミュレーションします。得点が格納されているファイルが存在する場合は、アプレットによってシリアル化可能クラス HighScore のインスタンスが復元され、復元された得点と新しい高得点が比較されます。新しい得点のほうが高ければ、そのクラスがファイルに書き込まれます。動作例を作成するには、このコードをアプレットにコピーして、[...] を有効な URL に置き換えます。
{curl 8.0 applet}
{import * from CURL.IO.SERIALIZE}
|| A class representing a "high score".
{define-class public serializable HighScore
field constant name:String
field constant score:int
{constructor {default name:String, score:int}
set self.name = name
set self.score = score
}
}
|| NOTE: Replace "[...]" below with a valid URL.
{let high-score-url:Url = [...]}
|| Start with "no" high score.
{let high-score:HighScore = {HighScore "nobody", 0}}
{try
|| Read any old high score.
{with-open-streams
in = {SerializeInputStream {read-open-byte high-score-url}}
do
set high-score = {deserialize in, HighScore}
}
catch e:MissingFileException do
|| The file may not exist yet.
}
|| NOTE: An actual game should be played here, but for this example,
|| we will just assume that a player named "somebody" beat the previous
|| high score by ten points.
{let name:String = "somebody"}
{let score:int = high-score.score + 10}
{if score > high-score.score then
|| Remember the new high score.
set high-score = {HighScore name, score}
|| Save the new high score.
{with-open-streams
out = {SerializeOutputStream {write-open-byte high-score-url}}
do
{out.write-one high-score}
}
}
次のコード サンプルでは、前のサンプルで定義した HighScore オブジェクトの配列を保存したり復元したりします。HighScore オブジェクトの配列全体が 1 つのデータ オブジェクトとして処理されていることに注意してください。動作例を作成するには、このコードをアプレットにコピーして、[...] を有効な URL に置き換えます。
{curl 8.0 applet}
{import * from CURL.IO.SERIALIZE}
|| A class representing a "high score".
{define-class public serializable HighScore
field constant name:String
field constant score:int
{constructor {default name:String, score:int}
set self.name = name
set self.score = score
}
}
|| A class representing a "high score list".
{define-class public serializable HighScoreList
field constant high-scores:{Array-of HighScore}
|| Add a new high score, and keep the top ten, sorted.
{method {add high-score:HighScore}:void
{self.high-scores.append high-score}
{self.high-scores.sort
comparison-proc =
{proc {hs1:HighScore, hs2:HighScore}:bool
{return hs1.score >= hs2.score}
}
}
{if self.high-scores.size > 10 then
{self.high-scores.remove 10, length = self.high-scores.size - 10}
}
}
{constructor {default}
set self.high-scores = {new {Array-of HighScore}}
}
}
|| NOTE: Replace "[...]" below with a valid URL.
{let high-score-list-url:Url = [...]}
|| The high score list.
{let high-score-list:HighScoreList = {HighScoreList}}
{try
|| Read the high score list, if it exists.
{with-open-streams
in = {SerializeInputStream {read-open-byte high-score-list-url}}
do
set high-score-list = {deserialize in, HighScoreList}
}
catch e:MissingFileException do
|| The file may not exist yet.
}
|| NOTE: An actual game should be played here, but for this example, we
|| will just assume that a player named "somebody" got a random score.
|| random number of points.
{let random:Random = {Random}}
{let score:int = {random.next-in-range 0, 999999}}
|| Add the new high score.
{high-score-list.add {HighScore "somebody", score}}
|| Save the high score list.
{with-open-streams
out = {SerializeOutputStream {write-open-byte high-score-list-url}}
do
{out.write-one high-score-list}
}
serializable クラスによって保存されたデータを Curl アプリケーションの新しいリリースで変更する場合は、define-serialization を使用して、新しいクラス定義でクラス バージョン番号にゼロより大きい整数を指定する必要があります。object-serialize メソッドは、クラス バージョンをシリアル化されたデータ ストリームの一部として書き込みます。既定のクラス バージョン番号はゼロ (0) です。
変更したクラスでも、着信データのクラス バージョンをチェックして適切に動作する object-deserialize コンストラクタを指定する必要があります。次の例では、when というフィールドを追加して、高得点が出た日付と時刻を格納します。
{define-class public serializable HighScore
field constant name:String
field constant score:int
field constant when:DateTime
{define-serialization class-version = 1}
{constructor public {object-deserialize in:SerializeInputStream}
let cv:int = {in.read-class-version}
set self.name = {deserialize in, String}
set self.score = {deserialize in, int}
{switch cv
case 0 do
set self.when = {DateTime}
case 1 do
set self.when = {deserialize in, DateTime}
else
{error "Unknown HighScore class-version ", cv, "."}
}
}
{constructor {default name:String, score:int}
set self.name = name
set self.score = score
set self.when = {DateTime}
}
}
このコード行では、クラス バージョンを 1 に設定します。
{define-serialization class-version = 1} object-deserialize コンストラクタは、まず着信データのクラス バージョンをチェックします。
let cv:int = {in.read-class-version}
次に、name および score フィールドに着信データを設定します。
set self.name = {deserialize in, String}
set self.score = {deserialize in, int}
そしてクラス バージョンを調べて、着信データのクラス バージョンが 1 であれば when フィールドにそのデータを設定します。データのクラス バージョンが 0 の場合は、着信データに日付情報は含まれていないため、アプレットは現在の日付と時刻を使用します。
{switch cv
case 0 do
set self.when = {DateTime}
case 1 do
set self.when = {deserialize in, DateTime}
else
{error "Unknown HighScore class-version ", cv, "."}
}
以下に示すデータ型のオブジェクトはシリアル化できます。
Copyright © 1998-2019 SCSK Corporation.
All rights reserved.
Curl, the Curl logo, Surge, and the Surge logo are trademarks of SCSK Corporation.
that are registered in the United States. Surge
Lab, the Surge Lab logo, and the Surge Lab Visual Layout Editor (VLE)
logo are trademarks of SCSK Corporation.