取得WinRAR 2.91版之後的RAR檔的解壓後的檔案總容量(支援2G以上大檔) |
|
japhenchen
高階會員 發表:51 回覆:444 積分:184 註冊:2003-07-23 發送簡訊給我 |
這是小弟第一次做出一點貢獻,可能對大家幫助不大,只是單純懶得用RAREXT.DLL來做這件事,順便自己練練功,學好File head & structure
function GetRarsize(fn: string): int64; var rar : tfilestream ; markblock ,mainblock , fileblock : array[0..6] of byte; fd,ob : array[0..24] of byte; filex : array[0..255] of char; BIGD : ARRAY[0..7] OF byte; fd2 : array of byte; unpsize : longword; osx : int64; maxa: int64; begin osx:=0; // 用來做offset跳躍用 result := 0 ; try rar:=tfilestream.Create(fn,fmOpenRead or fmShareDenyNone); // 開一個 File Stream maxa:=rar.Size; rar.Seek(0,soFromBeginning); // 跳到檔案開頭 rar.Readbuffer(markblock,7); // 讀Mark Block if (markblock[0]=$52)and(markblock[1]=$61)and(markblock[2]=$72)and(markblock[3]=$21)and (markblock[4]=$1A)and(markblock[5]=$07)and(markblock[6]=$00) then begin // 檢查Mark Block,確認是否為RAR格式 rar.Readbuffer(mainblock,7); // 讀取MAIN BLOCK (用來存放RAR註解的區段) osx:=mainblock[5] (mainblock[6]*$100); rar.Seek(osx-7,soFromCurrent); // 算佔用空間不需算註解,此段跳過 while rar.Read(fileblock,7)=7 do begin // 讀取FILE BLOCK(如果讀不到資料,則不進入程序) if fileblock[2]=$74 then begin // 檢查FLAG是不是$74(檔案)如是,則讀細部資料,如不是,則到ELSE段全跳過 rar.read(fd,25); // 讀取 FILE BLOCK裡的檔案細節資料 if ((fileblock[3] (fileblock[4]*$100)) and $100)=$100 then begin // 如果標示檔案超過2G,則... RAR.READ(BIGD,8); // 讀取超過2G大檔的細節資料(64位元組的高位部份),計算並加總容量 osx:=(((BIGD[0]) (BIGD[1]*$100) (BIGD[2]*$10000) (BIGD[3]*$1000000))*$100000000) (((fd[0]) (fd[1]*$100) (fd[2]*$10000) (fd[3]*$1000000))); result := result (((BIGD[4]) (BIGD[5]*$100) (BIGD[6]*$10000) (BIGD[7]*$1000000))*$100000000) (((fd[4]*$1) (fd[5]*$100) (fd[6]*$10000) (fd[7]*$1000000))); end else begin // 檔案不超過2G時則不用讀取8位元組的資料段,直接運算容量並與之前的數加總 osx:=(((fd[0]*$1) (fd[1]*$100) (fd[2]*$10000) (fd[3]*$1000000))); result := result (((fd[4]*$1) (fd[5]*$100) (fd[6]*$10000) (fd[7]*$1000000))); end; // 跳過檔名跟屬性設置段,用不到 rar.seek(osx,soFromCurrent); rar.seek(fd[19] (fd[20]*256),soFromCurrent); end else begin // 跳過非檔案(除錯、CRC、PASSWORD......) rar.Read(ob,25); osx:=(ob[0]*$1) (ob[1]*$100) (ob[2]*$10000) (ob[3]*$1000000); rar.Seek(osx,soFromCurrent); end; if form1.CheckBox1.Checked then break; end; end; finally rar.free; rar:=nil; end; end; |
領航天使
站長 發表:12216 回覆:4186 積分:4084 註冊:2001-07-25 發送簡訊給我 |
|
japhenchen
高階會員 發表:51 回覆:444 積分:184 註冊:2003-07-23 發送簡訊給我 |
底下的函式是用來取得RAR檔里所有檔案的清單,修改自頂樓那篇取得SIZE的CODE,所以就沒再當新文發表了
function GetRarList(fn: string):TStringList; var rar : tfilestream ; markblock ,mainblock , fileblock : array[0..6] of byte; fd,ob : array[0..24] of byte; filex : array[0..255] of char; BIGD : ARRAY[0..7] OF byte; fd2 : array of byte; unpsize : longword; osx : int64; rarini : TIniFile; begin osx:=0; // 用來做offset跳躍用 result := TStringList.Create; if fileexists(fn)=false then exit; try rar:=tfilestream.Create(fn,fmOpenRead or fmShareDenyNone); // 開一個 File Stream rar.Seek(0,soFromBeginning); // 跳到檔案開頭 rar.Readbuffer(markblock,7); // 讀Mark Block if (markblock[0]=$52)and(markblock[1]=$61)and(markblock[2]=$72)and(markblock[3]=$21)and (markblock[4]=$1A)and(markblock[5]=$07)and(markblock[6]=$00) then begin // 檢查Mark Block,確認是否為RAR格式 rar.Readbuffer(mainblock,7); // 讀取MAIN BLOCK (用來存放RAR註解的區段) osx:=mainblock[5] (mainblock[6]*$100); rar.Seek(osx-7,soFromCurrent); // 算佔用空間不需算註解,此段跳過 while rar.Read(fileblock,7)=7 do begin // 讀取FILE BLOCK(如果讀不到資料,則不進入程序) if fileblock[2]=$74 then begin // 檢查FLAG是不是$74(檔案)如是,則讀細部資料,如不是,則到ELSE段全跳過 rar.read(fd,25); // 讀取 FILE BLOCK裡的檔案細節資料 if ((fileblock[3] (fileblock[4]*$100)) and $100)=$100 then begin // 如果標示檔案超過2G,則... RAR.READ(BIGD,8); // 讀取超過2G大檔的細節資料(64位元組的高位部份),計算並加總容量 osx:=(((BIGD[0]) (BIGD[1]*$100) (BIGD[2]*$10000) (BIGD[3]*$1000000))*$100000000) (((fd[0]) (fd[1]*$100) (fd[2]*$10000) (fd[3]*$1000000))); end else begin // 檔案不超過2G時則不用讀取8位元組的資料段,直接運算容量並與之前的數加總 osx:=(((fd[0]*$1) (fd[1]*$100) (fd[2]*$10000) (fd[3]*$1000000))); end; // 跳過檔名跟屬性設置段,用不到 rar.Read(filex,fd[19]or(fd[20] shl 8)); result.Add(copy(filex,1,fd[19]or(fd[20] shl 8))); rar.seek(osx,soFromCurrent); // rar.seek(fd[19]or(fd[20] shl 8),soFromCurrent); end else begin // 跳過非檔案(除錯、CRC、PASSWORD......) rar.Read(ob,25); osx:=(ob[0]*$1) (ob[1]*$100) (ob[2]*$10000) (ob[3]*$1000000); rar.Seek(osx,soFromCurrent); end; end; end; finally rar.free; rar:=nil; end; end;我不懂,不懂,不懂....所以我才來ktop學工夫 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |