問題タブ [binaryformatter]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - さまざまなタイプを1つのファイルにシリアル化する
オブジェクトをシリアル化するためにを使用してBinaryFormatter
います。関連するリストにはさまざまなオブジェクトタイプがあります。すべてのオブジェクトを1つのファイルにシリアル化する「最良の」方法はありますが、逆シリアル化でそれらを分離することはできますか?現在、ファイル全体を逆シリアル化し、各オブジェクトの特定のフィールドをチェックして、逆シリアル化後にそれらを再追加する必要があるリストを確認しています。たとえば、すべてのフォード車には「FORD」フィールドがあり、トヨタには「TOYOTA」などがあります。逆シリアル化すると、オブジェクトを「foreach」し、「company」フィールドをチェックして、それらをに割り当てますList<Company>
。
これが最も効率的な方法かどうかはわかりません。助言がありますか?助けてくれてありがとう
.net - BinaryFormatterの代替
BinaryFormatterの代替品/交換品を購入しています。
BinaryFormatterで私が抱えている現在の問題(および代替案はこれに対処する必要があります)は、
1)下位互換性(以前のバージョンを使用してシリアル化されたクラスを逆シリアル化できます)
2)サイズ
3)速度 です
AltSerializerをチェックしましたが、速度に関していくつかの矛盾するレポートがありますが、下位互換性をサポートしているようです。
また、 protobuf-netも調べましたが、この段階では、すべての.protoファイルを定義する必要があるため、多くの作業が必要になる点が異なります。
おそらく、上記のいずれかまたは他の何かを使用している誰かがコメントしたいと思うでしょう。
c# - パフォーマンス: BinaryFormatter と XmlSerializer の比較
BinaryFormatter のパフォーマンスが XmlSerializer よりも優れていることをよく読みます。好奇心から、テストアプリを書きました。
すごい瞬間...なぜXmlはBinよりもはるかに高速なのですか(特に逆シリアル化)?
私の結果:
.net - .NET でシリアル化されたクラスをリファクタリングする方法は?
次の例のように、 BinaryFormatterによってディスクにシリアル化される C# クラスがあります。
後で、次の 1 つ以上によってこのクラスをリファクタリングしたい
- 名前を変更する -
名前空間を変更する
- 別のアセンブリに移動する
私が知る限り、バイナリ ファイルは、まったく同じ名前、名前空間、およびアセンブリ名を持つクラスが利用可能な場合にのみ逆シリアル化できます。
これを回避するにはどうすればよいですか? バージョン トレラント
シリアル化を壊すことなく、逆シリアル化を別のクラス名、名前空間、およびアセンブリにマップすることは可能ですか?
.net - .NETとBinaryFormatterの下位互換性
C#ゲームでBinaryFormatterを使用して、ユーザーのゲームの進行状況やゲームレベルなどを保存します。下位互換性の問題が発生しています。
目的:
- レベルデザイナーがキャンペーン(レベルとルール)を作成し、コードを変更しても、キャンペーンは正常に機能するはずです。これは、リリース前の開発中に毎日発生する可能性があります。
- ユーザーがゲームを保存します。ゲームパッチをリリースします。ユーザーは引き続きゲームをロードできるはずです。
- 目に見えないデータ変換プロセスは、2つのバージョンがどれほど離れていても機能するはずです。たとえば、ユーザーは最初の5つのマイナーアップデートをスキップして、6番目のアップデートを直接取得できます。それでも、彼の保存したゲームはまだ正常にロードされるはずです。
ソリューションは、ユーザーやレベルデザイナーには完全に見えないようにする必要があり、何かを変更したいコーダーに最小限の負担をかける必要があります(たとえば、より良い名前を考えたためにフィールドの名前を変更します)。
シリアル化するオブジェクトグラフの中には、あるクラスに根ざしているものもあれば、他のクラスに根ざしているものもあります。上位互換性は必要ありません。
変更を壊す可能性があります(古いバージョンをシリアル化し、新しいバージョンに逆シリアル化するとどうなりますか):
- フィールドを追加します(デフォルトで初期化されます)
- フィールドタイプの変更(失敗)
- フィールドの名前を変更します(フィールドを削除して新しいフィールドを追加するのと同じです)
- プロパティをフィールドに変更して元に戻します(名前の変更に相当)
- 自動実装プロパティを変更して、バッキングフィールドを使用するようにします(名前の変更に相当)
- スーパークラスを追加します(現在のクラスにフィールドを追加するのと同じです)
- フィールドを別の方法で解釈します(たとえば、度単位、現在はラジアン単位)
- ISerializableを実装する型の場合、ISerializableメソッドの実装を変更する場合があります(たとえば、非常に大きな型のISerializable実装内で圧縮の使用を開始します)
- クラスの名前を変更し、列挙値の名前を変更します
私はについて読んだ:
- バージョントレラントなシリアル化
- IDeserializationCallback
- [OptionalField(VersionAdded)]
- [OnDeserializing]、[OnDeserialized]、[OnSerializing]、[OnSerialized]。
- [シリアル化されていません]
私の現在の解決策:
- OnDeserializingコールバックなどを使用して、可能な限り多くの変更を中断せずに行います。
- 重大な変更は2週間に1回の予定であるため、維持する互換性コードは少なくなります。
- 重大な変更を加える前に、使用するすべての[Serializable]クラスを、OldClassVersions.VersionX(Xは最後の序数の次の序数)という名前空間/フォルダーにコピーします。すぐにリリースする予定がない場合でも、これを行います。
- ファイルに書き込む場合、シリアル化するのはこのクラスのインスタンスです。class SaveFileData {int version; オブジェクトデータ; }
- ファイルから読み取るとき、SaveFileDataを逆シリアル化し、次のようなことを行う反復的な「更新」ルーチンに渡します。
。
- 便宜上、Update()関数は、その実装で、リフレクションを使用して古いバージョンから新しいバージョンにできるだけ多くのデータをコピーするCopyOverlappingPart()関数を使用できます。このように、Update()関数は、実際に変更されたもののみを処理できます。
それに関するいくつかの問題:
- デシリアライザーは、クラスOldClassVersions.Version5.FooではなくクラスFooにデシリアライズします。これは、クラスFooがシリアル化されたものであるためです。
- テストやデバッグはほとんど不可能です
- 多くのクラスの古いコピーを保持する必要がありますが、これはエラーが発生しやすく、壊れやすく、煩わしいものです。
- クラスの名前を変更したいときにどうしたらよいかわかりません
これは本当に一般的な問題です。人々は通常どのようにそれを解決しますか?
c# - バイナリデータのマージ
私はこの質問をより短く、要点を絞って再フォーマットしています。BinaryFormatterのSerializeメソッドを使用して多数の異なるカスタムオブジェクトを実行すると、一連のシリアル化されたバイナリファイルが取得されます。アプリの保存/読み込み機能を使用して、これらのバイナリファイルをマージ/取得するための最良の方法は何ですか?
c# - C#非同期ソケット接続を介したシリアル化されたオブジェクトを含むオブジェクトのサイズの送信
オブジェクトをシリアル化してネットワーク経由で送信したい。クラスのISerializeable属性とBinaryFormatterを使用して、オブジェクトをバイトに変換するように設定しました。オブジェクトを送信し、受信側で逆シリアル化できます。ただし、オブジェクトを再構築する前にオブジェクト全体を確実に保持するために、ストリームと一緒にサイズを送信したいと思います。最初の数バイトをサイズとして設定し、受信したデータが少なくともこの固定サイズであるかどうかを確認すると、それを読み取ってオブジェクトのフルサイズを取得できます。次に、受信したデータがオブジェクトのサイズ+固定サイズのバイトになるまで待つだけです。オブジェクトのサイズを最初の数バイトとして格納し、オブジェクトを残りのバイトとして格納するintを送信できるように、ストリーム内のデータをオフセットするにはどうすればよいですか?
c# - 別のアプリケーションで BinaryFormatter を逆シリアル化する方法
BinaryFormatter を使用して、クラス インスタンスの配列をファイルにシリアル化しています。同じアプリケーション内でこの問題をデシリアライズできます。別のアプリケーション (作業を行う共通ファイルを取り込む) で同じ逆シリアル化を試みると、次のエラーが発生します。
ここで、pmlscan は元のアプリケーションの名前です。BinaryFormatter が pmlscan を読み込まないようにするにはどうすればよいですか?
.net-3.5 - .Net3.5のBinaryFormatterクラスでのメモリリークの問題
.Net3.5フレームワークのBinaryFormatterクラスでメモリリークの問題が発生しています。次のメソッドを使用してオブジェクトを逆シリアル化します。このメソッドに渡されるバイト配列のサイズは156MBです。ただし、このメソッドを呼び出した後、2.6GBのジャンプがあります。
このメモリリークの問題について説明しているMSDNの記事を見つけました。http://blogs.msdn.com/b/psirr/archive/2009/11/13/interesting-memory-leak-in-net-3-5-binary-deserialization.aspx
この問題の解決策があるかどうか誰かが知っていますか?.Net 4.0で解決されていますか?
c# - 同等の構造体への参照のコレクションを逆シリアル化するにはどうすればよいですか?
注:この質問は、問題について詳しく知るにつれて少し変わったので、全体を読んでください。問題がどのように発見され、最終的に解決されたかをよりよく説明しているため、元の形式のままにすることにしました。
私たちがC#やCLRを本当に理解していなかったとき、私たちのプロジェクトの歴史の最も暗い深さまでさかのぼって、私たちはタイプを作成しました。それを呼びましょうMyType
。この型をclass
参照型として作成しました。
MyType
しかし、値型である必要があることが明らかになっstruct
たので、それを行うためにいくつかの変更を加えました。ある日まで、MyType
値のコレクションを含むいくつかのデータを逆シリアル化しようとしました。そうではありませんが、それが参照型であった場合、そのコレクションは参照のコレクションでした。これで、逆シリアル化すると、コレクションはデフォルトのコンストラクターを使用して正常に逆シリアル化され、MyType
後で実際の参照が逆シリアル化されると、それらは孤立し、空の値のコレクションが残ります。
そこで、「ロード時に、参照が適切に解決されるように型を参照型にマップしてから、MyTypeRef
実行時と再シリアル化で使用するために実際の型に変換し直してみましょう」と考えました。したがって、(独自のバインダーを使用して)実行しましたが、残念ながら、との間の暗黙の変換があってもMyTypeRef[]
変換できないことを示すエラーが発生するため、機能しませんでした。MyType[]
MyTypeRef
MyType
だから、私たちは立ち往生しています。MyType
参照型のコレクションとしてシリアル化されたコレクションを取得して、値型のコレクションとして逆シリアル化するにはどうすればよいMyType
ですか?
更新
いくつかの調査(以下のコメントとコードを参照)は、実際の問題を引き起こしたのは、新しいものの不変の性質であり、シリアル化にMyType
使用されていることを示しています。ISerializable
なぜそうなるのかはまだわかりませんが、のprivate
代わりにsetアクセサーを使用するISerializable
と、新しいMyType
ものが古いものをロードします(ISerializable
使用するとインターフェイスが呼び出されますが、コレクションにはデフォルト値しか含まれていません)。
いくつかのコード
ロードするとき、要素はすべてnullであることに注意してください。2番目の定義から削除ISerializable
し、ロードするとすべてが機能します。ロードコードをオンに変更class
すると、同じ動作が表示されます。struct
これは、コレクションが設定されたアクセサーを使用してのみ正常に逆シリアル化されるかのようです。
更新2
それで、私は問題を見つけました(以下の私の答えを参照してください)が、私の質問を読んで誰かが答えを知っているとは思えません。当時重要だとさえ気づかなかった重要な詳細を見逃しました。助けようとした人たちに心からお詫び申し上げます。
ロードMyType
されたコレクションは、の間にすぐに別のコレクションにコピーされGetObjectData
ます。以下の答えは、これが重要であることが判明した理由を説明しています。完全な例を提供する、上記のサンプルコードに追加するサンプルコードを次に示します。