使用TextReader读取字节

4

过去,我一直使用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的Synchronized方法,代码如下:
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()方法,可以读取二进制文件?
2个回答

1
尝试使用File.ReadAllBytes()。然后,您可以使用MemoryStream从缓冲区中提取值。

1

你应该能够使用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一起使用。


嗯,我最初锁定了它,但我想我忘记锁定初始的seek()。为了安全起见,我还切换并开始预先读取内存流中的所有字节。 - user1914728

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接