BinaryReader 中缺失的一些方法





5.00/5 (12投票s)
BinaryReader 需要更好的方式来读取字符串和类型。这里提供一个快速且简单的解决方案
引言
也许只是为了证明我可以为你节省不到 5 分钟的时间,并换取一些有用的东西,给你吧。
BinaryReader
无法从流中读取固定长度或 ASCII 空字符结尾的字符串,这很不幸,因为很多文件都以这种方式存储字符串,无论好坏。此外,没有简单的方法可以读取整个结构中的数据,而无需读取每个单独的字段。
我最近再次实现了这个功能,因为似乎每次我这样做,代码都会被埋藏在某个地方,以至于重写它比找到它更容易。因此,这个技巧对我来说和你一样重要,尊敬的读者。
编写这个混乱的程序
这段代码非常短,我直接把它粘贴在这里供你使用。
using System;
using System.IO;
using System.Text;
using System.Runtime.InteropServices;
/// <summary>
/// Provides some conspicuously absent string and type functionality to
/// <seealso cref="BinaryReader"/>
/// </summary>
static class BinaryReaderExtensions
{
/// <summary>
/// Reads a class or a struct from the reader
/// </summary>
/// <typeparam name="T">The type to read</typeparam>
/// <param name="reader">The reader</param>
/// <returns>An instance of <typeparamref name="T"/> as read from the stream</returns>
public static T ReadType<T>(this BinaryReader reader)
{
byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
T result = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
handle.Free();
return result;
}
/// <summary>
/// Reads a C style null terminated ASCII string
/// </summary>
/// <param name="reader">The binary reader</param>
/// <returns>A string as read from the stream</returns>
public static string ReadSZString(this BinaryReader reader)
{
var result = new StringBuilder();
while (true)
{
byte b = reader.ReadByte();
if (0 == b)
break;
result.Append((char)b);
}
return result.ToString();
}
/// <summary>
/// Reads a fixed size ASCII string
/// </summary>
/// <param name="reader">The binary reader</param>
/// <param name="count">The number of characters</param>
/// <returns>A string as read from the stream</returns>
public static string ReadFixedString(this BinaryReader reader,int count)
{
return Encoding.ASCII.GetString(reader.ReadBytes(count));
}
}
使用这个烂摊子
将上述代码粘贴到你的代码文件后,只需像往常一样使用 BinaryReader
,只是现在你有了上述方法。请记住,你想要从文件中读取的任何类型都必须能够被编组。这意味着你可能需要实际将编组属性添加到你的类型中,才能使用 ReadType<>()
与它们一起使用。
在处理使用固定长度或空字符终止的 ASCII 存储字符串的旧文件时,读取这些 ASCII 字符串通常很有用。当你在流中遇到这样的字符串时,只需使用适当的方法来读取它。文档注释应该使一切清晰明了。
就这样了。希望对你有所帮助,如果现在没有帮助,那么将来某个时候也会有帮助。
历史
- 2021 年 4 月 23 日 - 初始提交