C# 相当于 C 的 fread 文件 i/o

2023-12-04

谁能告诉我如何在 C# .NET 版本 2 中以直接方式将字节数组放入结构中?就像熟悉的fread正如在 C 中所发现的,到目前为止,我在读取字节流和自动填充结构方面还没有取得太大成功。我见过一些实现,其中托管代码中存在指针骗局,方法是使用unsafe关键词。

看看这个示例:

public unsafe struct foobarStruct{

   /* fields here... */

   public foobarStruct(int nFakeArgs){
      /* Initialize the fields... */
   }

   public foobarStruct(byte[] data) : this(0) {
      unsafe {
         GCHandle hByteData = GCHandle.Alloc(data, GCHandleType.Pinned);
         IntPtr pByteData = hByteData.AddrOfPinnedObject();
         this = (foobarStruct)Marshal.PtrToStructure(pByteData, this.GetType());
         hByteData.Free();
      }
   }
}

我有两个构造函数的原因foobarStruct

  • 是否不能有一个空的构造函数。
  • 实例化结构时,将内存块(作为字节数组)传递到构造函数中。

该实现是否足够好,或者是否有更简洁的方法来实现这一目标?

Edit:我不想使用 ISerialized 接口或其实现。 我正在尝试读取二进制图像来计算出所使用的字段并使用 PE 结构确定其数据。


使用 P/Invoke 编组器没有任何问题,它并非不安全,并且您不必使用 unsafe 关键字。出错只会产生错误的数据。它比显式编写反序列化代码更容易使用,特别是当文件包含字符串时。您不能使用 BinaryReader.ReadString(),它假定字符串是由 BinaryWriter 写入的。但请确保使用结构声明来声明数据结构,this.GetType() 不太可能正常工作。

这是一个通用类,可以使其适用于任何结构声明:

  class StructureReader<T> where T : struct {
    private byte[] mBuffer;
    public StructureReader() {
      mBuffer = new byte[Marshal.SizeOf(typeof(T))];
    }
    public T Read(System.IO.FileStream fs) {
      int bytes = fs.Read(mBuffer, 0, mBuffer.Length);
      if (bytes == 0) throw new InvalidOperationException("End-of-file reached");
      if (bytes != mBuffer.Length) throw new ArgumentException("File contains bad data");
      T retval;
      GCHandle hdl = GCHandle.Alloc(mBuffer, GCHandleType.Pinned);
      try {
        retval = (T)Marshal.PtrToStructure(hdl.AddrOfPinnedObject(), typeof(T));
      }
      finally {
        hdl.Free();
      }
      return retval;
    }

文件中数据结构的示例声明:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
struct Sample {
  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 42)]
  public string someString;
}

您需要调整结构声明和属性以获得与文件中​​的数据匹配。读取文件的示例代码:

  var data = new List<Sample>();
  var reader = new StructureReader<Sample>();
  using (var stream = new FileStream(@"c:\temp\test.bin", FileMode.Open, FileAccess.Read)) {
    while(stream.Position < stream.Length) {
      data.Add(reader.Read(stream));
    }
  }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 相当于 C 的 fread 文件 i/o 的相关文章

随机推荐

  • @Dependent 范围在 Wildfly 中不是默认的吗?

    我在使用 Wildfly 通过 Inject 注入 POJO 时遇到一些麻烦 文档明确指出 Dependent 如果未指定 则默认范围 这意味着一个对象的存在只是为一个客户端 bean 提供服务 并且与该客户端 bean 具有相同的生命周期
  • 如何在Python线程中使用qtwebkit?

    我正在尝试使用 qtwebkit 解析 js 生成的网页 我找到了如何获取页面源的示例 import sys from PySide QtGui import from PySide QtCore import from PySide Qt
  • 如何测试更新方法?

    我是单元测试新手 并在我的 Java Spring Boot 应用程序中使用 JUnit 我有时需要测试更新方法 但是当我在网上搜索时 没有合适的示例或建议 那么 您能否澄清一下如何测试以下更新方法 我认为这可能需要与测试 void 不同的
  • 如何使用 beautifulsoup 打印 href 属性,同时通过 selenium 实现自动化?

    蓝色元素的 href 值是我想从此 HTML 访问的内容 我尝试了几种方法来打印链接 但没有成功 我的代码如下 discover page BeautifulSoup r text html parser finding accounts
  • 运行react-native run-android时出错

    https facebook github io react native docs getting started html I have followed the instruction that are on this link Bu
  • 在 Prolog 中对列表进行分区

    我正在尝试创建一个 Prolog 谓词 其中给定一个列表 可以看出该列表是否可以分为两个总和相同的列表 我有一个工作列表总和谓词 因此我在分区谓词中使用它 我首先尝试对谓词进行编码 以查看列表的第一个元素是否等于列表其余部分的总和 2 1
  • 通过 Office 365 REST API 标记消息?

    我正在寻找一种使用 Office 365 REST 消息 API 检测和设置电子邮件的 标记 状态的方法 我没有看到 Flag 被列为某个属性休息消息 尽管我确实看到它列在下面交换网络服务 我尝试进行 REST 调用 将 Flag 添加到筛
  • 如何在 Windows 窗体 C# 中执行代码时显示动画加载窗体

    我想在主窗体中执行一些代码时显示动画加载窗体 动画表单仅用于向用户显示操作正在执行 我想在操作完成后关闭它 我正在使用的代码是 public partial class Form main admin Form private Thread
  • Hibernate (JPA):当多个对象被修改和提交时如何处理 StaleObjectStateException

    考虑以下场景 一项数据库事务涉及不同表中的多个行并进行版本控制 例如 商店清单和产品 商店列表可能包含产品 及其在商店列表中的数量 并且产品具有当前库存 当我插入或编辑 shopList 时 我希望更新 shopList 中这些产品的库存以
  • Qml半透明模糊叠加矩形

    我正在尝试创建一个半透明模糊矩形 该矩形覆盖在 Qt Quick Qml 中的另一个矩形上 Rectangle id mainRect anchors fill parent color transparent This is my bac
  • 为什么带单引号的字符串在插入数据库时​​会引发错误?

    我的问题是 如何在字符串中允许单引号 例如 我有一个表单和一个文本框 它被设置为允许用户输入他们的名字 从那里 它发布数据并将其输入数据库 我需要能够允许使用单引号 撇号 因为有些人的名字中含有撇号 例如 O Reilly 有什么建议么 不
  • Android/Facebook:在墙上发布消息

    我想通过 Android 应用程序在我自己的墙上发布消息 我有方法 loginToFacebook 来登录 单击按钮时 如果用户已登录 我希望发布一条消息 我不太熟悉 facebook API 因此我查看了 facebook 开发人员文档和
  • Swift 中是否有比 u_long/UInt64 容量更大的数字类型?

    有没有比容量更大的类型u long or UInt64在斯威夫特 我有一个函数 它需要非常大的整数来识别 28 位的信用卡号码 func myFunc number What to put here body 什么类型合适 应该number
  • System.MissingMethodException:没有为此对象定义无参数构造函数

    我将 MVC 2 0 与 Html ListBoxFor 一起使用 如下所示
  • Azure AD B2C - 使用电子邮件或移动设备注册/登录

    我正在使用 Azure AD B2C 我们的产品团队向我们提出了一项偏好 要求 允许用户使用电子邮件地址或手机号码作为用户 ID 进行注册 登录 目前 内置流程仅允许电子邮件或用户名作为用户 ID 有有力的证据建议我们创建一个自定义策略以允
  • PushState 更改 - 相当于 Chrome 扩展 onHistoryStateUpdated

    我正在将 Chrome 扩展程序移植到 Firefox 扩展程序 由于其运行的网站的性质 我需要监视pushState Chrome 扩展有一个方便的方法来处理这个问题 chrome webNavigation onHistoryState
  • 如何使用 Pandas 转置将数据从一个数据帧添加到另一个数据帧?

    客观的 使用转置将一个数据帧填充到另一个数据帧 df pd DataFrame Attributes love family tech df T 产生以下输出 0 1 2 Attributes love family tech 其次 我有另
  • 在 iOS 6 中使用 SLRequest 与 Facebook

    我目前正在尝试使用 SLRequest 在 facebook 上发布状态 这是我的代码 ACAccountStore accountStore ACAccountStore alloc init ACAccountType accountT
  • 保存 html 画布图像

    我知道这个问题可能已经有了答案 但我还没有找到它 而且我的项目有一个截止日期 所以我制作了一个 html5 画布 我希望能够用一个 或多个 按钮做两件事 我希望用户能够通过单击 保存 按钮来保存他刚刚完成的操作 理想情况下我希望下载图像 而
  • C# 相当于 C 的 fread 文件 i/o

    谁能告诉我如何在 C NET 版本 2 中以直接方式将字节数组放入结构中 就像熟悉的fread正如在 C 中所发现的 到目前为止 我在读取字节流和自动填充结构方面还没有取得太大成功 我见过一些实现 其中托管代码中存在指针骗局 方法是使用un