Использование TextReader для чтения байтов

В прошлом я использовал BinaryReader для чтения нескольких байтов, но недавно я получил эту ошибку:

An error has occurred: Probable I/O race condition detected while copying memory. The I/O package is not thread safe by default. In multithreaded applications, a stream must be accessed in a thread-safe way, such as a thread-safe wrapper returned by TextReader's or TextWriter's Synchronized methods. This also applies to classes like StreamWriter and StreamReader.    at System.Buffer.InternalBlockCopy(Array src, Int32 srcOffset, Array dst, Int32 dstOffset, Int32 count)
   at System.IO.FileStream.Read(Byte[] array, Int32 offset, Int32 count)
   at System.IO.BinaryReader.FillBuffer(Int32 numBytes)
   at System.IO.BinaryReader.ReadUInt16()

Итак, в результате я решил использовать синхронизированные методы TextReader, например:

public class SafeReader
{
    private Stream m_Stream;
    private TextReader m_TextReader;
    public SafeReader(Stream stream)
    {
        m_TextReader = TextReader.Synchronized(new StreamReader(m_Stream = stream));
    }
    public Stream BaseStream
    {
        get { return m_Stream; }
    }
    public int ReadInt32()
    {
        // this doesn't even need to do anything (just has to read 4 bytes and it gets disposed of anyway);
        ReadUInt16();
        ReadUInt16();
        return -1;
    }
    public short ReadInt16()
    {
        return (short)(this.ReadUInt16());
    }
    public ushort ReadUInt16()
    {
        return BitConverter.ToUInt16(new byte[] { (byte)(m_TextReader.Read() & 0xFF), (byte)(m_TextReader.Read() & 0xFF) }, 0);
        //return (ushort)(((m_TextReader.Read() & 0xFF)) | ((m_TextReader.Read() & 0xFF) << 8));
    }
}

Однако возвращаемые значения (он в значительной степени читает изображение в проприетарном формате) неверен. «Изображения» имеют слегка голубоватый оттенок, и у меня есть ощущение, что это может быть вызвано тем фактом, что TextReader читает текст (и читает символы с кодировкой вместо просто чтения байтовых значений).

Есть ли "поточно-безопасный" способ, такой как TextReader Synchronized(), для чтения двоичных файлов?


person user1914728    schedule 19.12.2012    source источник


Ответы (2)


Вы должны иметь возможность использовать BinaryReaderвместо TextReader. Просто убедитесь, что вы lock массив в потоке, из которого вы к нему обращаетесь (записываете).

Object locker = new Object;

lock (locker) {
    //BinaryReader here
}

Из других потоков используйте то же самое:

lock (locker) {
    //read from array (read is thread-safe though)
}

Если в другом потоке выполняется операция записи, другой поток будет ждать, пока объект не будет разблокирован.

Вы также можете использовать File.ReadAllBytes, если вам не нужно читать кусками.

В качестве альтернативы используйте кодировку ASCII или UTF8 с Textreader.

person Community    schedule 19.12.2012
comment
Хм, я изначально заблокировал его, но я думаю, что забыл заблокировать начальный seek(). Я также переключился и начал читать все байты в потоке памяти заранее, просто на всякий случай. - person user1914728; 19.12.2012

Попробуйте File.ReadAllBytes(). Затем вы можете использовать MemoryStream для извлечения значений из буфера.

person Mir    schedule 19.12.2012