【问题标题】:Reading String from Stream从流中读取字符串
【发布时间】:2015-11-01 19:31:25
【问题描述】:

我正在将数据加密到流中。例如,如果我的数据是 Int32 类型,我将使用 BitConverter.GetBytes(myInt) 获取字节,然后将这些字节写入流中。

为了读回数据,我读取sizeof(Int32) 以确定要读取的字节数,读取这些字节,然后使用BitConverter.ToInt32(byteArray, 0) 将字节转换回Int32

那么我该如何使用字符串呢?写字符串没问题。但是读取字符串时的诀窍是知道要读取多少字节,然后才能将其转换回字符串。

我发现了类似的问题,但他们似乎假设字符串占据了整个流并且只是读取到流的末尾。但在这里,我可以在字符串前后添加任意数量的其他项目。

请注意,StringReader 在这里不是一个选项,因为我想要处理可能大于我想要加载到内存中的文件数据的选项。

【问题讨论】:

  • 您可能希望考虑使用BinaryReader/BinaryWriter 来读取和写入数据。它有处理字符串的方法。
  • @ScottChamberlain:谢谢,但最终我使用的是CryptoStream
  • 你可以做new BinaryReader(yourCryptoStream),只需将Stream 输入到二进制读取器/写入器的构造函数中。

标签: c# string stream


【解决方案1】:

您通常会发送内容长度标头,然后读取由该信息确定的长度。

这里是一些示例代码:

public async Task ContinouslyReadFromStream(NetworkStream sourceStream, CancellationToken token)
{
    while (!ct.IsCancellationRequested && sourceStream.CanRead)
    {
        while (sourceStream.CanRead && !sourceStream.DataAvailable)
        {
            // Avoid potential high CPU usage when doing stream.ReadAsync
            // while waiting for data
            Thread.Sleep(10);
        }

        var lengthOfMessage = BitConverter.ToInt32(await ReadExactBytesAsync(stream, 4, ct), 0);
        var content = await ReadExactBytesAsync(stream, lengthOfMessage, ct);
        // Assuming you use UTF8 encoding
        var stringContent = Encoding.UTF8.GetString(content);

    }
}


protected static async Task<byte[]> ReadExactBytesAsync(Stream stream, int count, CancellationToken ct)
{
    var buffer = new byte[count];
    var totalBytesRemaining = count;
    var totalBytesRead = 0;
    while (totalBytesRemaining != 0)
    {
        var bytesRead = await stream.ReadAsync(buffer, totalBytesRead, totalBytesRemaining, ct);
        ct.ThrowIfCancellationRequested();
        totalBytesRead += bytesRead;
        totalBytesRemaining -= bytesRead;
    }
    return buffer;
}

【讨论】:

    【解决方案2】:

    想到的解决方案是提供一个预定的标记值来表示字符串的结束(例如,ASM 使用 0 字节),或者在每个之前提供一个固定长度的元数据块新的数据类型。在该元数据块中将包含类型和长度,以及您认为包含的任何其他有用信息。

    为了紧凑,如果可以在您的系统中使用,我会使用 sentinel 值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-13
      • 1970-01-01
      • 2014-01-26
      • 2012-10-24
      • 2018-03-21
      • 2016-10-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多