2016-08-20 189 views
0

作爲一個前言,這是我第一個正確的C#程序,而我在編程方面的經驗主要是爲TES5Edit製作Pascal腳本。在拉撒路做了兩個實際的節目,但是,呃,他們非常糟糕。C# - 從已知偏移量的文件中獲取字節

上傳我當前的代碼「埃雷:http://www.mediafire.com/download/fadr8bc8d6fv7cf/WindowsFormsApplication1.7z

總之!我目前正在嘗試做的是獲取.dds文件中兩個特定偏移量的字節值。 x分辨率保持@ offset + 0c,並由兩個字節(so + 0c和+ 0d)組成。 y決議的同樣演出; @ offset +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()函數等效的十六進制,否?

+0

所以基本上你是問如何從一個特定的文件偏移讀取小端編碼'ushort'。 –

+0

對,呃,LE和BE是按字節順序做的;所以在LE中,十六進制值4000被寫爲'00 40',但是在BE中,它被寫爲'40 00',是的?而ushort似乎只是一個小整數變量。 – MajinCry

+0

正確。實際上查看數據,很可能它們是在偏移0xc處的LE'int(s)(4字節),0xc + 4 –

回答

3

第一,使用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); 

,並呼籲ReadByte或它Read方法獲取儘可能多的字節。讀取字節之後,流中的位置將按讀取的字節數提前。您可以使用Position屬性獲取流中的當前位置。要直接從流中讀取小端值,可以使用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(); 
} 
+1

'BitConverter'不保證使用little endian。要使用的正確類是'BinaryReader'。 –

+0

你是對的,謝謝。我更新了答案。 – ArgusMagnus

+0

慢慢地處理文檔。原諒我沒有及時發帖,我以蝸牛的速度編碼。當您使用'Seek()'函數時,我認爲它將返回的值傳遞給下一個函數?似乎與議會的'cmp'和'je'功能相似;當前者被調用時,結果被放到下一行代碼中,這通常是je(或某種派生),即根據cmp是否返回true或false而(不)傳遞。 – MajinCry

相關問題