使用TextReader读取字节

时间:2012-12-19 04:40:17

标签: c# encoding 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的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 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

您应该可以使用BinaryReader代替TextReader。只需确保lock您访问它的线程上的数组(写入)。

Object locker = new Object;

lock (locker) {
    //BinaryReader here
}

从其他线程使用相同的:

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

如果正在进行写操作,则另一个线程将等待对象解锁。

如果您不需要读取块,也可以使用File.ReadAllBytes

或者使用Textreader的ASCII或UTF8编码。