question

fangfangwu avatar image
fangfangwu asked ·

How to write and read multiple types of data using Data Writer and Data Reader

I need to write a file length, file data and its type as a string value to the stream.

I’m using the following code with Data Writer.
writer = new DataWriter(socket.OutputStream);

 // if we have a StorageFile named file
 using (var stream=await file.OpenStreamForReadAsync())
 using(var ms=new MemoryStream())
 {
     await stream.CopyToAsync(ms);
     var bytes = ms.ToArray();
     writer.WriteUInt32(Convert.ToUInt32(bytes.Length));
     writer.WriteString("Video");
     writer.WriteBytes(ms.ToArray());
     await writer.StoreAsync();
 }

And I tried to read that value using Data Reader as following.

 try
 {
     while (true)
     {
     //Read first 4 bytes(length of the subsequent string).
     uint sizeFieldCount = await reader.LoadAsync(sizeof(uint));
       if (sizeFieldCount != sizeof(uint))
         {
            // The underlying socket was closed before we were able to read the whole data.
             return;
         }
    
     // Read the string.
     uint fileLength = reader.ReadUInt32();
     uint actualFileLength = await reader.LoadAsync(fileLength);
     if (fileLength != actualFileLength)
         {
         // The underlying socket was closed before we were able to read the whole data.
         return;
     }
     String type = reader.ReadString(5);
    
      var bytes = new byte[actualFileLength];
     reader.ReadBytes(bytes);
                    
      var file = await ApplicationData.Current.LocalFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
          await FileIO.WriteBytesAsync(file, bytes);
     }
 }
 catch (Exception exception)
 {
        // If this is an unknown status it means that the error is fatal and retry will likely fail.
    
 }

But the problem is that when I’m reading the data using Data Reader, I can't read file data. It throws System Exception.
Is there a way to write and read multiple types of data using Data Writer and Data Reader?

windows-uwpwindows-uwp-runtime
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

RoyLi-MSFT avatar image
RoyLi-MSFT answered ·

Hello,


Welcome to our Microsoft Q&A platform!

First, the reason why you have the error is that the DataReader is not fully loaded.
Your data consists of uint, string and byte array.

 uint fileLength = reader.ReadUInt32();
 uint actualFileLength = await reader.LoadAsync(fileLength);

This above code indicates that you loaded the fileLength length data in the DataReader, but in fact, this part of the data contains a string value of length 5.
So when you read the string value, the remaining data is not enough to fill your byte array, as a result, you will get an error.
To meet your needs, you need to call LoadAsync method twice.
Like this:

 uint sizeFieldCount = await reader.LoadAsync(sizeof(uint));
 if (sizeFieldCount != sizeof(uint))
 { 
     return;
 }
 uint fileLength = reader.ReadUInt32();
 // Read the string.
 await reader.LoadAsync(5);
 string type = reader.ReadString(5);
 // Read the bytes.
 uint actualFileLength = await reader.LoadAsync(fileLength);
 if (fileLength != actualFileLength)
 {
     return;
 }
 var bytes = new byte[actualFileLength];
 reader.ReadBytes(bytes);

Thanks





Share
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.