none
[UWP] Write and read multiple types of data using Data Writer and Data Reader RRS feed

  • Question

  • Hi,

    I needed to write a file length, file data and its type as a string value to the stream. So I tried as following.

    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.
    
                }

    Even though I can read the string value, 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?

    Thanks

    Monday, September 23, 2019 3:17 AM

Answers

  • Hi,

    The reason 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 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, so you will get an error.

    In order to meet your needs, you need to call LoadAsync twice.

    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);

    Best regards.


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by SanderSeny Tuesday, October 1, 2019 5:01 AM
    Monday, September 23, 2019 8:20 AM

All replies

  • Hi,

    The reason 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 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, so you will get an error.

    In order to meet your needs, you need to call LoadAsync twice.

    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);

    Best regards.


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by SanderSeny Tuesday, October 1, 2019 5:01 AM
    Monday, September 23, 2019 8:20 AM
  • Thanks Richasy, it worked !!!
    Tuesday, October 1, 2019 5:01 AM