【问题标题】:C# - Get bytes from file at known offsetC# - 从已知偏移量的文件中获取字节
【发布时间】:2016-12-27 15:09:30
【问题描述】:

作为一个小小的前注,这是我第一个正确的 C# 程序,我的编程经验主要是为 TES5Edit 制作 Pascal 脚本。在 Lazarus 中制作了两个实际的程序,但是,呃,它们非常糟糕。

上传了我当前的代码'ere:http://www.mediafire.com/download/fadr8bc8d6fv7cf/WindowsFormsApplication1.7z

无论如何!我目前正在尝试做的是获取 .dds 文件中两个特定偏移量的字节值。 x 分辨率保持@offset +0c,由两个字节组成(即+0c 和+0d)。 y 分辨率的相同演出; @ 偏移 +10 和 +11。我在这里上传了我的发现:http://pastebin.com/isBKwaas

但是,我不知道该怎么做。我能够从各种谷歌搜索结果中破译的最多的结果是这样的:

        public void GetDDSDimensions(string strDDSFilename, out int iSourceDDSx, out int iSourceDDSy)
    {
        FileStream fsSourceDDS = new FileStream(strDDSFilename, FileMode.Open, FileAccess.Read);
        int iWidthOffset = 12; // 0c in hex, if byte is 00, then size is => 256, so get +0d as well
        int iHeightOffset = 16; // 10 in hex, same gig as above. Get byte @ +11 if +10 is 00.
        byte[] bufferDDSBytes = new byte[24]; // @ Offset +24 , byte is always 01. Use as a wee, err, "landmark".

    }

不知道如何从那里继续前进。我需要以某种方式设置 bufferDDSBytes 以获取 fsSourceDDS 中的前 24 个字节,然后比较十六进制值@+0c 和 +10,以获得 .dds 文件的分辨率。

比较应该很容易; C# 应该有一个等效于 Pascal 的 StrToInt() 函数的十六进制,不是吗?

【问题讨论】:

  • 所以基本上你是在问如何从特定的文件偏移量读取 Little-endian 编码的ushort
  • 对,呃,LE和BE是跟字节顺序有关的;所以在 LE 中,十六进制值 4000 写为 '00 40',但在 BE 中,它写为 '40 00',是吗?而 ushort 似乎只是一个小的整数变量。
  • 正确。实际看数据,很可能是 LE int s (4 bytes) at offset 0xc, 0xc+4

标签: c# windows visual-studio visual-studio-2013 windows-7


【解决方案1】:

首先,使用using :-)

using (FileStream fsSourceDDS = new FileStream(strDDSFilename, FileMode.Open, FileAccess.Read))
{
     // do something with the FileStream
} // Ensures that it is properly closed/disposed

要转到流中的特定偏移量,请使用Seek 方法:

fsSourceDDS.Seek(someOffset, SeekOrigin.Begin);

并在其上调用ReadByteRead 方法以获取尽可能多的字节。读取字节后,流中的位置按读取的字节数前进。您可以使用Position 属性获取流中的当前位置。要直接从流中读取 little-endian 值,您可以使用 BinaryReader 类。

结合以上所有:

using (FileStream fsSourceDDS = new FileStream(strDDSFilename, FileMode.Open, FileAccess.Read))
using (BinaryReader binaryReader = new BinaryReader(fsSourceDDS))
{
    fsSourceDDS.Seek(0x0c, SeekOrigin.Begin);
    ushort with = binaryReader.ReadUInt16();
    fsSourceDDS.Seek(0x10, SeekOrigin.Begin);
    ushort height = binaryReader.ReadUInt16();
}

【讨论】:

  • BitConverter 不保证使用小端序。要使用的正确类是BinaryReader
  • 慢慢阅读文档。请原谅我没有及时发布,我以蜗牛的速度编码。当您使用“Seek()”函数时,我认为它将返回值传递给下一个函数?似乎类似于 Assembly 的 'cmp' 和 'je' 功能;当前者被调用时,结果被扔到下一行代码,这通常是 je(或一些派生词),即(不)根据 cmp 返回 true 或 false 传递。
  • 无论如何都可以缩短为using (var reader = new BinaryReader(File.OpenRead(strDDSFilename))) { reader.BaseStream.Position = 0xc; int width = reader.ReadInt32(); int height = reader.ReadInt32(); } +1。
  • @MajinCry:(Un)幸运的是,我不知道汇编程序,所以我不确定我是否正确理解了你的问题。您熟悉 OO(面向对象编程)和类的概念吗?如果没有,您应该阅读它。 Seek(与许多实例方法一样)修改FileStream 实例的状态(此处为 fsSourceDDS),在这种情况下您可以忽略返回值,它“知道”当前位置。但是解释这个对于评论来说太长了..
猜你喜欢
  • 2012-11-30
  • 2014-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多