Curl® 言語 API は、データ ストリームの非同期読み取りをサポートします。非同期アクセスにより、バックグラウンドでデータを読み取りながらアプレットを起動したり実行し続けたりすることができます。これはまた、アプレットが開いてデータ ストリームを読み取っているときにユーザーがアプレットと対話する必要がある場合にも役立ちます。この手法により、ユーザーは、時間がかかりすぎている場合にストリーム操作を取り消し、待機中にアプレットを使用した他のアクションを実行することができます。
非同期入出力が役立つのは、応答が遅かったり入手できなかったりすることがあるインターネット ソースからのデータにアクセスする場合や、大量のデータにアクセスする場合などです。
以下のプロシージャは、
Url から非同期読み取りを行うものです。
次の例では、
async-read-from を使用して、テキスト ファイルから非同期に読み取ります。エラー処理を行い、ストリーム データを
buffer に書き込むイベント ハンドラを使用して作業することができます。
テキストの読み取りやデータベースからのデータ レコードの取得など、いくつかの場合には、読み取り処理全体が完了する前に、partial? = true を使用してデータの表示を開始したいことがあります。
注意: 以下の例では、読み取り操作に character-encoding = "shift-jis" が使用されています。
ユーザーが選択したファイルとこの文字エンコーディング間に互換性がない場合はエラーがスローされます。
例:
async-read-from の使用 |
 |
{paragraph
Please click the button below and select a text file to read
in. There is a text file located at
{{url "curl://install/docs/default/support/example.txt"}.canonicalize}
if you cannot find one.
}
{let buffer:TextFlowBox =
{TextFlowBox width = 5in, border-width = 1pt,
border-color = "black", margin = 2pt
}
}
{let rdr:#AsyncStreamReader}
{let cancel-button:CommandButton =
{CommandButton
label = "Cancel reading",
{on Action do
{if-non-null rdr then
{rdr.cancel}
}
}
}
}
{set cancel-button.enabled? = false}
{VBox
{CommandButton
label = "Select File to Read",
{on Action do
{buffer.clear}
let file-url:#Url = {choose-location}
{if-non-null file-url then
set rdr =
{async-read-from
file-url,
|| partial? = true means that this will be called
|| for each chunk of data that is downloaded.
partial? = true,
character-encoding = "shift-jis",
{on asre:AsyncStreamReadEvent do
{if-non-null e = asre.exception then
{buffer.add
""
}
else
let buf:#StringBuf =
(asre.data asa #StringBuf)
{if-non-null buf then
{buffer.add buf}
}
{if asre.canceled? then
{buffer.add ""}
}
}
{if asre.exception != null or asre.canceled? or
asre.done?
then
set cancel-button.enabled? = false
}
}
}
set cancel-button.enabled? = true
}
}
},
cancel-button,
buffer
}
| |
以下のプロシージャは、
Url からのストリームを非同期で開くものです。
これらのプロシージャは、1 つ以上の
EventHandler を引数として受け取ります。これらのイベント ハンドラは
AsyncFileOpenEvent を受け取る必要があります。
AsyncFileOpenEvent はストリームを含みますが、開けなかった場合は例外を含みます。これらのイベント ハンドラで、ストリームに対してアクション (ストリームからの読み取りなど) を実行します。これらのプロシージャは、ストリームへの直接アクセスが必要な場合に使用する必要があります。また、ストリームを閉じる必要もあります。
async-read-open プロシージャは、テキストを文字列として読み取りたくない場合や、ファイルを開く必要はあるが、他のイベントが発生するか、ユーザーからの追加入力があるまでファイルを読み取りたくない場合に役立ちます。また、直ちにストリームの一部を読み取り、後でストリームからの追加読み取りを実行する必要がある場合にも、このプロシージャを使用しなければなりません。
async-read-from を使用してストリームの一部を読み取ることができますが、その読み取りが完了すると、ストリームは閉じます。
注意: 以下の例では、読み取り操作に character-encoding = "shift-jis" が使用されています。
ユーザーが選択したファイルとこの文字エンコーディング間に互換性がない場合はエラーがスローされます。
例:
async-read-open の使用 |
 |
{paragraph
Please click the button below and select a text file for
asynchronous read. There is a text file located at
{{url "curl://install/docs/default/support/example.txt"}.canonicalize}
if you cannot find one.
}
{let status-buffer:TextFlowBox =
{TextFlowBox width = 5in, border-width = 1pt,
border-color = "black", margin = 2pt
}
}
{let buffer:TextFlowBox =
{TextFlowBox width = 5in, border-width = 1pt,
border-color = "black", margin = 2pt
}
}
{define-proc public {handle-successful-open-event
afoe:AsyncFileOpenEvent
}:AsyncStreamReader
let str:TextInputStream =
(afoe.stream asa TextInputStream)
{status-buffer.add
{text
}
}
let rdr:AsyncStreamReader =
{str.async-read-string
|| we will get called multiple times
|| as data comes in.
partial? = true,
|| The data that we get will be
|| appended to, and so will have all
|| of the data so far.
append? = true,
{on asre:AsyncStreamReadEvent do
{if-non-null e = asre.exception then
{status-buffer.add
{paragraph
color = "red",
}
}
else
let buf:#StringBuf =
(asre.data asa #StringBuf)
{if-non-null buf then
{status-buffer.add
{paragraph
Read has seen
{value buf.size} chars.
}
}
{buffer.clear}
{buffer.add buf}
}
{if asre.canceled? then
{status-buffer.add
{paragraph
color = "red",
}
}
elseif asre.done? then
{status-buffer.add
{paragraph Read has completed.}
}
}
}
{if (asre.exception != null or asre.done?) and str.open? then
{str.close}
}
}
}
{return rdr}
}
{VBox
{CommandButton
label = "Select File to Read",
{on Action do
{buffer.clear}
{status-buffer.clear}
let file-url:#Url = {choose-location}
{if-non-null file-url then
let opr:AsyncFileOpener =
{async-read-open
file-url,
character-encoding = "shift-jis",
{on afoe:AsyncFileOpenEvent do
{if-non-null e = afoe.exception then
{status-buffer.add
{paragraph
color = "red",
}
}
elseif afoe.canceled? then
{status-buffer.add
{paragraph
color = "red",
}
}
else
let rdr:AsyncStreamReader =
{handle-successful-open-event afoe}
|| rdr could be used for canceling.
}
}
}
}
}
},
status-buffer,
buffer
}
| |
次の例では、バイナリ データを開いて読み取るための非同期プロシージャを使用します。これらのプロシージャはテキストの場合と非常によく似ています。例では
InputStream-of.async-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 opr:AsyncFileOpener =
{async-read-open-byte
file-url,
{on afoe:AsyncFileOpenEvent do
{if-non-null e = afoe.exception then
{popup-message "Open failed: " & e}
elseif afoe.canceled? then
{popup-message "Open was canceled."}
else
|| open succeeded
let my-input:ByteInputStream =
(afoe.stream asa ByteInputStream)
let rdr:AsyncStreamReader =
{my-input.async-read
{on asre:AsyncStreamReadEvent do
{if-non-null e = asre.exception then
{popup-message
"Read failed: " & e
}
else
let data:#{Array-of byte} =
(asre.data asa
#{Array-of byte})
{if-non-null data then
{results.add
{text
Got {value data.size}
bytes of data from the
file.
}
}
}
{if asre.canceled? then
{popup-message
"Read was canceled."
}
}
}
|| close the stream since we are
|| done with it.
{my-input.close}
}
}
}
}
}
|| you could save opr and rdr so that you can call cancel
|| on either of them if you wanted to cancel a request due
|| to the user requesting it or it taking too long.
}
}
},
results
}
| |
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.