2015-08-10 4 views
1

Я шифрую данные в поток. Если, например, мои данные имеют тип Int32, я буду использовать BitConverter.GetBytes(myInt), чтобы получить байты, а затем записать эти байты в поток.Чтение строки из потока

Чтобы прочитать данные обратно, я прочитал sizeof(Int32), чтобы определить количество байт для чтения, читать эти байты, а затем использовать BitConverter.ToInt32(byteArray, 0), чтобы преобразовать байты обратно в Int32.

Так как бы я сделал это со строкой? Написание строки не проблема. Но трюк при чтении строки - это знать, сколько байтов нужно прочитать, прежде чем я смогу преобразовать ее обратно в строку.

Я нашел похожие вопросы, но они, похоже, считают, что строка занимает весь поток и только что читается до конца потока. Но здесь я могу иметь любое количество других элементов до и после строки.

Отметьте, что StringReader здесь не является вариантом, так как я хочу иметь возможность обрабатывать данные файла, которые могут быть больше, чем я хочу загрузить в память.

+0

Вы можете посмотреть, чтобы с помощью [BinaryReader] (https://msdn.microsoft.com/en-us/library/system.io.binaryreader (v = vs.110) .aspx)/BinaryWriter для чтения и записи ваших данных. Он имеет методы обработки строк в нем. –

+0

@ScottChamberlain: Спасибо, но в конечном итоге я использую 'CryptoStream'. –

+1

Вы можете сделать новый BinaryReader (yourCryptoStream) ', просто подайте« 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; 
} 
1

Решения, которые приходят на ум, должны либо предоставить предопределенное значение дозорной силы, чтобы сигнализировать конец строки (например, ASM использует 0 байтов для этого), либо для обеспечения заранее запланированного блока метаданных каждого нового типа данных. В этом блоке метаданных будет тип и длина, а также любая другая информация, которую вы сочтете полезной для включения.

Для компактности я бы использовал значение дозорного устройства, если оно будет работать в вашей системе.

Смежные вопросы