• 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 进制数据,

    并且存储为 二进制数据。

    操作截图:

    显示的 16 进制输出:

    页面的 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";
            }
  • 相关阅读:
    《大数据之路:阿里巴巴大数据实践》——7-章 数据挖掘
    《如何做到毫秒级从百亿大表任意维度筛选数据?》
    《大数据之路:阿里巴巴大数据实践》——6-章 数据服务
    《【原创】推荐系统
    给机器学习面试者的十项建议 | 面试官角度
    干货 | NLP算法岗大厂面试经验与路线图分享
    目标检测任务中的训练宝典 |实用技巧
    食物图片变菜谱:这篇CVPR论文让人人都可以学习新料理
    一文彻底搞懂BP算法:原理推导+数据演示+项目实战(下篇)
    CVPR 2019细粒度图像分类竞赛中国团队DeepBlueAI获冠军 | 技术干货分享
  • 原文地址:https://www.cnblogs.com/hebeiDGL/p/2701630.html
Copyright © 2020-2023  润新知