質問
Kobata Makoto · 2022年2月28日

Native API for .NETでの%Stream.GlobalBinaryデータの書き込みについて

皆様こんにちは。

Native API for .NETを使用して、%Stream.GlobalBinaryタイプのプロパティを持つデータを作成しようとしています。

%Stream.GlobalBinaryタイプのプロパティ(binaryData)に書き込む部分は以下のようになっています。

Using obj As InterSystems.Data.IRISClient.ADO.IRISObject = iris.ClassMethodObject("User.Sample","%New")

        Using prop As InterSystems.Data.IRISClient.ADO.IRISObject = obj.GetObject("binaryData")

                prop.InvokeStatusCode("Write", binary)

        End Using

        obj.InvokeStatusCode("%Save")

End Using

この”Write”メソッド部分ですが、1.5MB程度の制限がかかってしまい、1.5MBを超えるようなデータが登録できません。

※実際にはエラーとはならず、1.5MBまでしか書き込まれていない状態のようです。

どなたか解決方法等ご教授いただけないでしょうか。

Product version: IRIS 2020.3
$ZV: IRIS for Windows (x86-64) 2020.3 (Build 304U) Tue Oct 27 2020 10:07:42 EDT
0
0 89
ディスカッション (8)2
続けるにはログインするか新規登録を行ってください

@Kobata Makoto さん、こんにちは。

ちょっと状況が違うかもしれませんが、私の環境(Visual Studio2019、IRISは2021.2と2021.1)ですと、
MAXSTRINGエラーがでて途中で終わってしまいました。(おそらく、Write()メソッドに360万文字越えの情報を渡したときにエラーが出ていそうです)

試しに、以下のように Write()メソッドに分割して渡したところ、5MBの画像データもIRISに保存できました。

Dim obj As IRISObject = native.ClassMethodObject("User.Sample", "%New")
Dim prop As IRISObject = obj.GetObject("binaryData")
Dim filename As String = "C:\kit\test.png"
Dim inputFile = IO.File.Open(filename, IO.FileMode.Open)
Dim bytes = New Byte(5000) {}

While inputFile.Read(bytes, 0, bytes.Length) > 0
 prop.InvokeStatusCode("Write", bytes)
End While

obj.InvokeStatusCode("%Save")

@Mihoko Iijima さん、ご返答ありがとうございます。

エラーこそ出ませんが、現象としては同じだと思います。

確かに分割してWriteすれば書き込めますが、どうしてもレスポンスが下がるので

何とかしたいな〜と思ってます...「IRISになったら遅くなった」とは言われたくないですし><

ちなみに、Readも1回では読み込めないようです...

他の方法も検討してみます。ありがとうございました!

@Hiroshi.Satoさん

ご無沙汰しております。先日のVirtual Summitはとても良い勉強になりました!

ポスト拝見いたしました。正にこの中のNative APIによる読み書きとなります。

試してはおりませんが、おそらく同ソースでも1.5MB以上では切れるのではないかと思います。

ADO含め代案を検討してみようと思っています。

ありがとうございました!

kobataさん
ご視聴ありがとうございました。

私のサンプルで2M以上のファイルでもOKでした。
私のサンプルは、.Netの標準ライブラリーであるSystem.IO.FileStreamを使っています。

なので同じRead,Writeメソッドでも中の実装は違っていると思います。
 

>私のサンプルは、.Netの標準ライブラリーであるSystem.IO.FileStreamを使っています。

>なので同じRead,Writeメソッドでも中の実装は違っていると思います。

これは全然関係ないコメントでした。

バージョンはいくつを使っていますか?
 

私が使用しているのは、

2021.2 (Build 650U)

です。

新しいバージョンを使うといろいろと改善されていることがあったりするので、是非最新を試すようにしてみてください。

でもあんまり巨大なファイルを一度で読み書きするのは結局ディスクの読み書きやプロセスのメモリーのアロケーションやいろいろなことが絡んでくるので一筋縄ではいかないこともありそうです。

ちなみに

360万文字越えのデータは無理です。

サーバー側のWriteメソッドが受け付けるのは、普通のIRISの文字列なので、その最大値の制限は受けてしまいます。

バージョンは2021.1を使用しています。

.NET Managed Providerでは360万文字の制限を受けなかった(1回のWriteコールで完了)ので、

同じようにNative APIで実装していました。とりあえずデータを分割する方向で現在検討中です。

ありがとうございました!