ticket。 Converting a Binary Stream into a Text Stream Converting a binary stream into a text stream involves using the …provided formatter to create a Ticket instance that is then converted into text。 The following is the plete source code (you’ll need a reference to LottoLibrary in Binary2Text)。 Imports System。IO Imports System。Runtime。Serialization。Formatters。Binary Public Class LottoTicketProcessor : Implements IBinary2TextProcessor Public Sub Process(ByVal input As Stream; ByVal output As TextWriter) _ Implements IBinary2TextProcessor。Process Dim builder As StringBuilder = New StringBuilder() Try Do While True Dim formatter As BinaryFormatter = New BinaryFormatter() Dim ticket As LottoLibrary。Ticket = _ DirectCast(formatter。Deserialize(input); LottoLibrary。Ticket) …………………………………………………………Page 298…………………………………………………………… 276 CH AP T E R 1 0 ■ L E A R N I N G A B OU T P E R S IS TE N CE builder。AppendFormat( _ 〃{0}。{1}。{2} {3} {4} {5} {6} {7} {8} {9} {10}〃; ticket。DrawDate。Year; ticket。DrawDate。Month; ticket。DrawDate。Day; ticket。Numbers(0); ticket。Numbers(1); ticket。Numbers(2); ticket。Numbers(3); ticket。Numbers(4); ticket。Numbers(5); ticket。Bonus; ControlChars。NewLine) Loop Catch e As Exception End Try output。Write(builder。ToString()) End Sub End Class In the code; a binary stream is read using the BinaryFormatter class; which reads the data for an object from the data stream。 Notice how the method Deserialize() does not ask which type to read。 This is because all of that information is saved in the stream。 Deserialize() will read data from the stream; associate the data with a type; instantiate it; and populate the data members。 The bolded code in the preceding listing points out where deserialization bees tricky; which centers around when to read what type。 A binary stream when processed by the BinaryFormatter will read and write objects。 BinaryFormatter will instantiate whatever it encoun ters and assumes that the caller of BinaryFormatter knows which type is being manipulated。 If the caller does not know this; an exception will occur because the type cast to the specific type will fail。 The exception block is necessary because you don’t know how many Ticket objects have been saved; as the count has not been saved to the stream。 provides the Position and Length properties to determine if any instances are left to be read; but those properties work only with files。 If the binary stream being read is a console data stream; there is no length or position。 Thus; the only real solution is to keep reading until you can’t do so anymore and assume processing is plete。 INTENTION AND IMPLEMENTATION The fact that Position and Length have different behaviors depending on the implementation might seem to break the contract of being able to separate intention from implementation。 It seems to break the po nent software paradigm because; as a developer; you do need to know about the stream implementation。 The rule has not been broken; but been put on hold; because sometimes you are left with no other option。 A file stream and console stream share many characteristics; but knowing the length is not one of them。 A programmer could force the console stream to give back some value; but that would be incorrect。 The smarter approach; and the one chosen by the implementers; is to generate an exception。 …………………………………………………………Page 299…………………………………………………………… CH A PT E R 1 0 ■ L E A R N I N G A B O U T P E R S IS T E N CE 277 The binary stream formatter can bee even pickier。 Look at Figure 10…8 again and notice how the type information with version identifiers is stored in the stream。 Imagine the situation where you create an assembly that saves some objects。 Then x years and n versions of the program later; you try to load the file。 You can’t; because the version of the type does not exist。 It is smart for the binary formatter to not instantiate a version of a type that does not exist; because otherwise there could be serialization failures。 Tweaking Serialization When dealing with serialization; you may e across a particular text or binary format that will require some extra work。 Also; you may have some objects that you want to exclude from serialization。 Performing Custom Serialization Sometimes I think there are as many file formats as there are grains of sand on a beach。 As just two examples; specializations of text formats are XML and JSON (for JavaScript Object Notation; used in JavaScript for your web browser)。 In most cases; the default serializations will work。 However; you may need to tweak a particular serialization。 Many serialization techniques allow custom serializations of a particular object。 The default serialization implies a certain marshaling。 For example; it might