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

FindFirst()的 屬性 參數是多餘的??

答題得分者是:BGman
builder78
初階會員


發表:36
回覆:100
積分:47
註冊:2003-02-03

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-02-07 13:48:30 IP:210.85.xxx.xxx 未訂閱
void __fastcall TForm1::Button1Click(TObject *Sender) { String FileName; TSearchRec SearchRec; int iAttributes_01 = 0; int iAttributes_02 = 0; iAttributes_01 |= faReadOnly * true; //只找唯讀 iAttributes_02 |= faAnyFile * true; //全部檔案 String Dir=ExtractFilePath(Application->ExeName); if (FindFirst(Dir "*.*", iAttributes_01, SearchRec) == 0) //尋找全部檔案中屬性為唯讀的檔案 { do { if ((SearchRec.Attr & iAttributes_02) == SearchRec.Attr) //真正的屬性比對是這一行 { Memo1->Lines->Add(SearchRec.Name); //結果Memo顯示全部檔案而不管屬性是否唯讀 } } while (FindNext(SearchRec) == 0); FindClose(SearchRec); } } /*但結果是秀出全部檔案不管屬性是否唯讀,因為FindFirst與FindNext根本不比對屬性 !! 真正的屬性比對是我們的程式在比對,那這樣的話FindFirst的第二個參數根本沒作用 而且顯得很多餘 是這樣子嗎??? 再問第二個問題 TSearchRec結構中用一個int型別(32bit)來表示檔案的 size 這是否暗示一個檔案的大小不能超過4G ??? */
RaynorPao
版主


發表:139
回覆:3622
積分:7025
註冊:2002-08-12

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-02-07 14:24:05 IP:203.73.xxx.xxx 未訂閱
引言: void __fastcall TForm1::Button1Click(TObject *Sender) { String FileName; TSearchRec SearchRec; int iAttributes_01 = 0; int iAttributes_02 = 0; iAttributes_01 |= faReadOnly * true; //只找唯讀 iAttributes_02 |= faAnyFile * true; //全部檔案 String Dir=ExtractFilePath(Application->ExeName); if (FindFirst(Dir "*.*", iAttributes_01, SearchRec) == 0) //尋找全部檔案中屬性為唯讀的檔案 { do { if ((SearchRec.Attr & iAttributes_02) == SearchRec.Attr) //真正的屬性比對是這一行 { Memo1->Lines->Add(SearchRec.Name); //結果Memo顯示全部檔案而不管屬性是否唯讀 } } while (FindNext(SearchRec) == 0); FindClose(SearchRec); } } /*但結果是秀出全部檔案不管屬性是否唯讀,因為FindFirst與FindNext根本不比對屬性 !! 真正的屬性比對是我們的程式在比對,那這樣的話FindFirst的第二個參數根本沒作用 而且顯得很多餘 是這樣子嗎??? 再問第二個問題 TSearchRec結構中用一個int型別(32bit)來表示檔案的 size 這是否暗示一個檔案的大小不能超過4G ??? */
builder78 你好: (1)請改成以下這樣看看 < class="code"> void __fastcall TForm1::Button1Click(TObject *Sender) { String FileName; TSearchRec SearchRec; int iAttributes_01=faReadOnly; int iAttributes_02=faAnyFile; if(FindFirst("C:\\*.*", iAttributes_02, SearchRec)==0) { do { if(SearchRec.Attr & iAttributes_01) { Memo1->Lines->Add(SearchRec.Name); } } while (FindNext(SearchRec)==0); FindClose(SearchRec); } } (2)理論上應該是這樣子的(不過這點我不是很確定) --
------
-- 若您已經得到滿意的答覆,請適時結案!! --
-- 欲知前世因,今生受者是;欲知來世果,今生做者是 --
-- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 --
BGman
初階會員


發表:28
回覆:85
積分:42
註冊:2003-01-10

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-02-07 14:41:41 IP:211.22.xxx.xxx 未訂閱
問題一,關於這個函式,他是正常的。我看了你的程式發現其中一個判斷式的運算元有點用錯了,於是我將你的程式稍微改了一下< class="code"> void __fastcall TForm1::Button1Click(TObject *Sender) { String FileName; TSearchRec SearchRec; int iAttributes_01 = 0; int iAttributes_02 = 0; iAttributes_01 |= faReadOnly ; //只找唯讀 iAttributes_02 |= faAnyFile ; //全部檔案 String Dir=ExtractFilePath(Application->ExeName); if (FindFirst(Dir "*.*", iAttributes_02, SearchRec) == 0) //尋找全部屬性的檔案 { do { if ((SearchRec.Attr | iAttributes_01 ) == SearchRec.Attr) //尋找唯讀的檔案 { Memo1->Lines->Add(SearchRec.Name); } } while (FindNext(SearchRec) == 0); FindClose(SearchRec); } } if ((SearchRec.Attr | iAttributes_01 ) == SearchRec.Attr) 檔案的屬性,Windows刻意設計成 0x001 0x010 0x100 ...以精簡儲存的位元數 所以你在這裡應該要用 |OR 而非 &AND,雖然FindFirst 第二的參數看起來不好用,以你的例子來說,你試著把FindFirst下iAttributes_01/iAttributes_02 來比較還是具有過濾檔案及檔案夾的功能。 問題二,4G 的確是32 bit int type 的瓶頸,如果想要操作大於 4G 建議你改用ULARGE_INTEGER才能辦到
builder78
初階會員


發表:36
回覆:100
積分:47
註冊:2003-02-03

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-02-07 15:07:23 IP:210.85.xxx.xxx 未訂閱
謝謝版主的回答~ 不過你給的程式並無法證明FindFirst的屬性參數有無作用? 不過卻讓我知道了下列: (1) //表示檔案屬性只要符合所設定屬性中的任何一個屬性即可 if(SearchRec.Attr & iAttributes_01) (2) //表示檔案屬性一定要符合所設定屬性中的全部屬性才可以 ??? <= 這第二點的程式碼 要怎表示呢??
RaynorPao
版主


發表:139
回覆:3622
積分:7025
註冊:2002-08-12

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-02-07 15:13:43 IP:203.73.xxx.xxx 未訂閱
引言: 謝謝版主的回答~ 不過你給的程式並無法證明FindFirst的屬性參數有無作用? 不過卻讓我知道了下列: (1) //表示檔案屬性只要符合所設定屬性中的任何一個屬性即可 if(SearchRec.Attr & iAttributes_01) (2) //表示檔案屬性一定要符合所設定屬性中的全部屬性才可以 ??? <= 這第二點的程式碼 要怎表示呢??
builder78 你好:
(2)如果想要符合全部的屬性,請參考以下的做法
   >    -- 
        
------
-- 若您已經得到滿意的答覆,請適時結案!! --
-- 欲知前世因,今生受者是;欲知來世果,今生做者是 --
-- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 --
builder78
初階會員


發表:36
回覆:100
積分:47
註冊:2003-02-03

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-02-07 15:38:00 IP:210.85.xxx.xxx 未訂閱
To:BGman if ((SearchRec.Attr | iAttributes_01 ) == SearchRec.Attr) 的意義是甚麼呢?我試試了一下 發現只有唯讀檔案會顯示出來~ 若是 唯讀 隱藏 的檔案 是無法顯示出來的 To:RaynorPao 版主 你好像不太了解我的意思耶~~ To:大家 我第一個問的問題的意思是 ~ 我執行一個FindFirst或FintNext的函數~ 檔名用*.* 屬性用表示不限制檔名~ 但屬性限制為唯讀~ 這時為何函數還是將 全部的檔名都傳回?? 而不管檔案屬性是否唯讀?? 我已經跟設定了函數的屬性參數說了我只要唯讀檔!! 但最後的函數卻沒過濾 而將全部檔案傳回~ 難道函數只過濾檔名 而不過濾屬性嗎?~ 搞到最後 屬性的判斷還是要我們自行寫程式來判斷~ 既然如此這函數的屬性參數 不就是無用的ㄇ?
BGman
初階會員


發表:28
回覆:85
積分:42
註冊:2003-01-10

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-02-07 17:20:33 IP:211.22.xxx.xxx 未訂閱
首先你必須要研究Windows的檔案系統二進位與十六進位的運算 一般的檔案屬性值為32 一般加上唯讀為33 一般加上唯讀加隱藏為35,依此類推 如果FindFirst 參數下faReadOnly (0x01) 到時候經過過濾只會留下32, 因為以 0x01 篩選太嚴格了,0x01 不包含 35 (二進位的運算) 第二關if((SearchRec.Attr | faReadOnly ) == SearchRec.Attr) 完全篩不到 所以建議你第一關用faAnyFile 第二關在利用六個屬性來搭配篩選。 沒有必要浪費時間在FindFirst 的參數上,因為這只是Borland 將RunTime  Library " findfirst " 包成 VCL,目的也只是提供一個掃描檔案的機制而已 所以請參考下列程式:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  String FileName;
  TSearchRec SearchRec;
  String Dir=ExtractFilePath(Application->ExeName);
  if (FindFirst(Dir "*.*", faAnyFile, SearchRec) == 0) //尋找全部屬性的檔案
  {
    do
    {
      if ((SearchRec.Attr | faReadOnly | faHidden) == SearchRec.Attr) //尋找唯讀加隱藏的檔案
      {
        Memo1->Lines->Add(SearchRec.Name);
      }
    } while (FindNext(SearchRec) == 0);
  FindClose(SearchRec);
  }
}
builder78
初階會員


發表:36
回覆:100
積分:47
註冊:2003-02-03

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-02-07 19:20:58 IP:210.85.xxx.xxx 未訂閱
感謝 BGman 大大的解說~ 大概有點了解了~ 看來FindFirst的屬性參數雖然有點作用但用處不大~ 補充一下 if((iAttributes & SearchRec.Attr) == iAttributes) if ((iAttributes | SearchRec.Attr) == SearchRec.Attr) 以上兩個式子是相等的~ ^^
系統時間:2024-04-20 0:50:50
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!