25、DataReaderWriter

 

 

1、Read and write simple structured data:

      这个示例演示了创建一个内存支持的流,然后通过使用 DataWrite 对象把下面的字符串存储到流中。一旦这个

操作完成了,再使用一个 DataReader 对象把这些字符串从这个流中提取出来。

   

操作截图:

 

点击按钮后 ,显示结果:

 

页面的 xaml:

//将要操作的文本

 <TextBlock x:Name="ElementsToWrite" >

            Hello;World;1 2 3 4 5;Très bien!;Goodbye

 </TextBlock>



  <Button x:Name="SendButton" Content="Copy Strings" Click="TransferData"/>
//输出结果

<TextBlock x:Name="ElementsRead"  />

 

按钮的操作事件:

 

//读取文本框中的文本,并使用 DataReader 和 DataWriter 进行读写操作

 private async void TransferData(object sender, RoutedEventArgs e)

        {

            // 初始化 in-memory stream ,并把数据存储到这个流中

            using (var stream = new Windows.Storage.Streams.InMemoryRandomAccessStream())

            {

             // 创建数据写入器对象支持的内存流

                using (var dataWriter = new Windows.Storage.Streams.DataWriter(stream))

                {

                  // 获取或设置用于输出流的 Unicode 字符编码。 编码为 UTF-8。

                    dataWriter.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;



                 // 在输出流中获取或设置数据的字节顺序。首先存储最低有效字节(最低的地址)。

                    dataWriter.ByteOrder = Windows.Storage.Streams.ByteOrder.LittleEndian;



                 // 转换输入流,并且把它们分割

                    string[] inputElements = ElementsToWrite.Text.Split(';');

                    foreach (string inputElement in inputElements)

                    {

                     // 获取字符串的大小。

                        uint inputElementSize = dataWriter.MeasureString(inputElement);



                    //将 32 位无符号整数值写入输出流。

                        dataWriter.WriteUInt32(inputElementSize);



                    //将字符串值写入输出流。

                        dataWriter.WriteString(inputElement);

                    }



                    // 发送 writer 的内容到支持的流。

                       await dataWriter.StoreAsync();



                //对于内存流的实现中,我们调用 flushAsync() 方法是多余的,但是其它类型的流中可能需要这么做



                   // 为了延长 stream 的生命周期,把这个流从 dataWriter 中分离,所以在 dataWriter 对象调用 Dispose() 方法时,
//这个流不会被关闭掉。如果我们分离这个流失败,在调用dataWriter.Dispose() 方法时会优先关闭这个流,阻止了下面DataReader 的调用
dataWriter.DetachStream(); } // 创建这个 input stream 在位置 0,以便这个流可以从开始读 using (var inputStream = stream.GetInputStreamAt(0)) { using (var dataReader = new Windows.Storage.Streams.DataReader(inputStream)) { // 编码和字节顺序需要匹配我们之前的设置使用的 writer // 获取或设置用于输入流的 Unicode 字符编码。 dataReader.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8; // 在输入流中获取或设置数据的字节顺序。 dataReader.ByteOrder = Windows.Storage.Streams.ByteOrder.LittleEndian; // 一旦我们把这些内容写成功,然后我们就加载这个流. 从输入流加载数据。 await dataReader.LoadAsync((uint)stream.Size); var receivedStrings = ""; // 继续阅读,直到我们消费掉完整的流。 while (dataReader.UnconsumedBufferLength > 0) { // 注意到当调用 ReadString 方法前需要设置 “code units”的长度。 //这是为什么在写入流时,把每个 string 的长度进行设置 uint bytesToRead = dataReader.ReadUInt32(); receivedStrings += dataReader.ReadString(bytesToRead) + "\n"; } // 把从流中读取的元素输出到 TextBlock 对象中 ElementsRead.Text = receivedStrings; } } }

 

 2、Dump file contents using ReadBytes() :

      本示例打开下面图片的顺序访问流,并且使用 ReadBytes() 方法,把它的内容显示为 16 进制数据,

并且存储为 二进制数据。

 

操作截图:

25、DataReaderWriter

 

显示的 16 进制输出:

25、DataReaderWriter

 

页面的 xaml :

//用来操作的应用程序包中的图片

<Image x:Name="StrawberryImage" Source="/assets/110Strawberry.png"  />



<Button x:Name="HexDumpButton" Content="Hex Dump"  Click="HexDump"/>



//显示图片的 16 进制结果

 <TextBlock x:Name="ReadBytesOutput"  />

 

相应按钮的单击事件:

//声明三个变量

private const int bytesPerRow = 16;

private const int bytesPerSegment = 2;

private const uint chunkSize = 4096;





//首先打开将要操作的图片,然后把文件放入一个连续访问的流中,然后使用 ReadBytes() 方法从中提取二进制数据。最后,把每个字节转换为 16 进制的数据,
//并且格式化后,把这些数据输出到 textblock 中
private async void HexDump(object sender, RoutedEventArgs e) { try { //检索并获取图形文件 Uri uri = new Uri("ms-appx:///assets/110Strawberry.png"); var file = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(uri); // 打开一个图像文件的顺序访问流。 using (var inputStream = await file.OpenSequentialReadAsync()) { // 把这个输入流(input stream)传输到 DataReader 对象 using (var dataReader = new Windows.Storage.Streams.DataReader(inputStream)) { uint currChunk = 0; uint numBytes; ReadBytesOutput.Text = ""; // 创建一个字节数组,可以持有足够的字节来填充一排十六进制转储。 var bytes = new byte[bytesPerRow]; do { // 加载下一个块 到 DataReader 的缓冲区 numBytes = await dataReader.LoadAsync(chunkSize);//从输入流加载数据。
// 读出并打印一行 var numBytesRemaining = numBytes; while (numBytesRemaining >= bytesPerRow) { // 使用 DataReader 对象和 ReadBytes() 方法来填补这个字节数组与足够一行的字节 dataReader.ReadBytes(bytes);//从输入流中读取字节值数组。
PrintRow(bytes, (numBytes
- numBytesRemaining) + (currChunk * chunkSize)); numBytesRemaining -= bytesPerRow; } // 如果有任何剩余的字节可读,分配一个新的数组,用来装载 DataReader对象中剩余的字节,并且打印到最后一行
// 注意: ReadBytes()填充整个数组,所以如果数组被传入到比在 DataReader 中剩下的缓冲区大
//,将会抛出一个异常。
if (numBytesRemaining > 0) { bytes = new byte[numBytesRemaining]; //  从输入流中读取字节值数组。
dataReader.ReadBytes(bytes); PrintRow(bytes, (numBytes - numBytesRemaining) + (currChunk * chunkSize)); } currChunk++;
// If the number of bytes read is anything but the chunk size, then we've just retrieved the last // chunk of data from the stream. Otherwise, keep loading data into the DataReader buffer.
//如果读取的字节数决不是块的大小,然后我们检索下一个
//大块的数据流。否则,继续加载数据到 DataReader 缓冲区。
} while (numBytes == chunkSize); } } } catch (Exception ex) { ReadBytesOutput.Text = ex.Message; } }

 

        /// <summary>

        /// 把从 ReadBytes() 方法中得到的数据,格式化并且输出为一行十六进制数据

         /// </summary>

        /// <param name="bytes">我们将要操作的数组</param>

        /// <param name="currByte">值将被格式化为一个地址</param>

        private void PrintRow(byte[] bytes, uint currByte)

        {

            var rowStr = "";



            // Format the address of byte i to have 8 hexadecimal digits and add the address

            // of the current byte to the output string.

            rowStr += currByte.ToString("x8");



            // 格式化输出

              for (int i = 0; i < bytes.Length; i++)

            {

                //如果完成了一段,添加一个 空格。

                  if (i % bytesPerSegment == 0)

                {

                    rowStr += " ";

                }



              // 把当前字节值转换成十六进制,并将它添加到输出字符串。

                rowStr += bytes[i].ToString("x2");

            }



             // 把当前行追加到 TextBlock 中

               ReadBytesOutput.Text += rowStr + "\n";

        }

 

 

你可能感兴趣的:(Writer)