Бинарный ридер и писатель открыты одновременно? - PullRequest
4 голосов
/ 28 декабря 2011

Я пишу код, который имеет дело с файлом, который использует хэши.Мне нужно прочитать фрагмент, затем хэшировать его, затем записать, затем прочитать другой фрагмент и т. Д.

Другими словами, мне нужно много читать и писать.Я уверен, что это действительно просто, но я просто хотел, чтобы это делали профессионалы ...

Возможно ли и допустимо ли сделать что-то вроде:

BinaryReader br = new BinaryReader (File.OpenRead(path));
BinaryWriter bw = new BinaryWriter (File.OpenWrite(path));
br.dostuff();
bw.dostuff();

Я помнюпри эксперименте с открытием и записью файлов возникала ошибка, связанная с конфликтом файловых потоков, и я не уверен, что я сделал, чтобы получить его.Это проблема двух потоков файлов?Могу ли я иметь один поток для чтения и записи?

1 Ответ

2 голосов
/ 28 декабря 2011

Это вполне возможно и желательно. С технической точки зрения, если ваш метод записи не меняет длину файла и всегда находится позади читателя, это не должно создавать никаких проблем.Фактически, с точки зрения API, это желательно, поскольку это позволяет пользователю контролировать, где читать и куда писать.(Рекомендуется специфицировать запись в другой файл, если во время процесса шифрования произойдет что-то плохое, ваш входной файл не будет испорчен).

Что-то вроде:

protected void Encrypt(Stream input, Stream output)
{
    byte[] buffer = new byte[2048];

    while (true)
    {
        // read 
        int current = input.Read(buffer, 0, buffer.Length);
    if (current == 0)
                     break;

        // encrypt
        PerformActualEncryption(buffer, 0, current);

        // write
        output.Write(buffer, 0, current);
    }   
}

public void Main()
{
    using (Stream inputStream  = File.Open("file.dat", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    using (Stream outputStream = File.Open("file.dat", FileMode.Open, FileAccess.Write, FileShare.ReadWrite))
    {
        Encrypt(inputStream, outputStream);
    }
}

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

class MySpecialHashingStream : Stream
{
...
}

protected void Encrypt(Stream input, Stream output)
{
    Stream encryptedOutput = new MySpecialHashingStream(output);
    input.CopyTo(encryptedOutput);
}
...