【问题标题】:Using TextReader to read bytes使用 TextReader 读取字节
【发布时间】:2012-12-19 04:40:17
【问题描述】:

过去,我一直在使用 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() 这样的“线程安全”方式来读取二进制文件?

【问题讨论】:

    标签: c# encoding textreader


    【解决方案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 编码。

    【讨论】:

    • 嗯,我最初锁定了它,但我想我忘了锁定最初的 seek()。为了安全起见,我还切换并开始读取内存流中的所有字节。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-21
      • 2016-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多