全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1220
推到 Plurk!
推到 Facebook!

取得WinRAR 2.91版之後的RAR檔的解壓後的檔案總容量(支援2G以上大檔)

 
japhenchen
高階會員


發表:51
回覆:444
積分:184
註冊:2003-07-23

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-09-29 16:40:08 IP:211.96.xxx.xxx 未訂閱
這是小弟第一次做出一點貢獻,可能對大家幫助不大,只是單純懶得用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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-09-29 19:47:45 IP:211.76.xxx.xxx 未訂閱
感謝分享程式 程式不論大小 總會有值得別人參考之處 再次感謝您 ~~~Delphi K.Top討論區站長~~~
------
~~~Delphi K.Top討論區站長~~~
japhenchen
高階會員


發表:51
回覆:444
積分:184
註冊:2003-07-23

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-10-29 16:49:37 IP:211.96.xxx.xxx 未訂閱
底下的函式是用來取得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學工夫
系統時間:2024-07-01 21:47:04
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!