如何取出TMemoryStream的片段並比較呢? |
尚未結案
|
chtai
高階會員 發表:68 回覆:238 積分:116 註冊:2004-05-21 發送簡訊給我 |
我的問題是這樣的,目前我想要寫個簡單分析midi檔的程式
之前有好心人建議我可以先把midi檔讀進TMemoryStream裡再處理
可以減少許多 I/O 的動作.
而且TMemoryStream裡的東東就是一個個BYTE了,拿來分析也比較方便.
可是現在問題來了,midi檔裡頭有分許多的小部分(chunk), 而每個部分的檔頭不太一樣,我必須依據檔頭來決定要怎麼分析這一部分. 檔頭看起來如下: 4D 54 68 64 00 00 00 06 ff ff nn nn dd dd ----這是第一種 4D 54 72 6B xx xx xx xx ----這是第二種 在第一種裡,是由4D546864 (ASCII的 Mthd )開頭 在第二種裡,是由4D54726B (ASCEE的 Mtrk )開頭 我要怎麼做才能取出一個片段(例如:開頭的4個Byte) 並比較它是等於某一字串(例如 Mthd 或是 Mtrk )呢? 搜尋了站上的文章,似乎都只提到怎麼對一個Byte或Word處理, 而沒提到要如何處理一個片段哩~ (若是只能一個個Byte比對,那光是比對一個檔頭就要好幾層的 if 耶 @@) 還請大家教導小弟了~~
------
My Web: http://nelson.csie.us My Blog: http://blog.nelson.csie.us |
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
如果您的資料是 4 bytes 為單位,可以直接把它變成 int 或 unsigned int 的陣列,例如:
unsigned int *Buf=(unsigned int *)Stream->Memory; int DataCount=Stream->Size/4; for(int i=0;i
------
http://www.ViewMove.com |
chtai
高階會員 發表:68 回覆:238 積分:116 註冊:2004-05-21 發送簡訊給我 |
|
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
unsigned char *Buf=(unsigned char *)Stream->Memory; // 1 byte: Label1->Caption=AnsiString(Buf[i]); // 2 bytes: unsigned short *usData=(unsigned short *)&Buf[i]; Label1->Caption=AnsiString(*usData); // 4 bytes: unsigned int *uiData=(unsigned int *)&Buf[i]; Label1->Caption=AnsiString(*uiData); // 其他特殊的 bytes 組合: (以 3 bytes 為例) unsigned int Data=Buf[i 0] Buf[i 1]<<8 Buf[i 2]<<16; Label1->Caption=AnsiString(Data); // 以上是假設 [i 0] 是低位元組,[i 2] 是高位元組,如果高低相反,則 unsigned int Data=Buf[i 2] Buf[i 1]<<8 Buf[i 0]<<16; Label1->Caption=AnsiString(Data);最後,關於 10 進位... 其實,存在電腦內的都是 2 進位,但電腦語言都會提供轉成人看的 10 進位函式。像一般的 int 變數,它存在記憶體內當然是 2 進位的型式,而需要轉出來看時,用 IntToStr() 就可以看到其 10 進位的數值。在使用 BCB 時,AnsiString 的功能算是很強的,幾乎把任何東西丟給它,它都可以轉換,再找個 Label 或是放入 ListBox,Memo 來看都行。 http://www.ViewMove.com 視動自動化科技股份有限公司 ViewMove Technologies, Inc. 發表人 - dllee 於 2004/05/30 20:58:17
------
http://www.ViewMove.com |
chtai
高階會員 發表:68 回覆:238 積分:116 註冊:2004-05-21 發送簡訊給我 |
|
aquarius
資深會員 發表:3 回覆:347 積分:330 註冊:2003-05-21 發送簡訊給我 |
不用這麼麻煩吧!! 用 CompareMem 就可以比較兩段 Memory 的內容了!!
引言:...Aquariusunsigned char *Buf=(unsigned char *)Stream->Memory; // 1 byte: Label1->Caption=AnsiString(Buf[i]); // 2 bytes: unsigned short *usData=(unsigned short *)&Buf[i]; Label1->Caption=AnsiString(*usData); // 4 bytes: unsigned int *uiData=(unsigned int *)&Buf[i]; Label1->Caption=AnsiString(*uiData); // 其他特殊的 bytes 組合: (以 3 bytes 為例) unsigned int Data=Buf[i 0] Buf[i 1]<<8 Buf[i 2]<<16; Label1->Caption=AnsiString(Data); // 以上是假設 [i 0] 是低位元組,[i 2] 是高位元組,如果高低相反,則 unsigned int Data=Buf[i 2] Buf[i 1]<<8 Buf[i 0]<<16; Label1->Caption=AnsiString(Data);最後,關於 10 進位... 其實,存在電腦內的都是 2 進位,但電腦語言都會提供轉成人看的 10 進位函式。像一般的 int 變數,它存在記憶體內當然是 2 進位的型式,而需要轉出來看時,用 IntToStr() 就可以看到其 10 進位的數值。在使用 BCB 時,AnsiString 的功能算是很強的,幾乎把任何東西丟給它,它都可以轉換,再找個 Label 或是放入 ListBox,Memo 來看都行。 http://www.ViewMove.com 視動自動化科技股份有限公司 ViewMove Technologies, Inc. 發表人 - dllee 於 2004/05/30 20:58:17
------
水瓶男的blog: http://791909.blogspot.com |
chtai
高階會員 發表:68 回覆:238 積分:116 註冊:2004-05-21 發送簡訊給我 |
|
aquarius
資深會員 發表:3 回覆:347 積分:330 註冊:2003-05-21 發送簡訊給我 |
引言: Aquarius兄您好: 小弟不曾用過這個函式哩~ 不知您是否願意就這個例子說明一下要如何使用呢?很簡單使用呀!! 請看 HELP Performs a binary comparison of two memory images. Unit SysUtils Category comparison routines Delphi syntax: function CompareMem(P1, P2: Pointer; Length: Integer): Boolean; assembler ; C syntax: extern PACKAGE bool __fastcall CompareMem(void * P1, void * P2, int Length); Description CompareMem performs a binary compare of Length bytes of memory referenced by P1 to that of P2. CompareMem returns true if the memory referenced by P1 is identical to that of P2. ...Aquarius
------
水瓶男的blog: http://791909.blogspot.com |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |