線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:5569
推到 Plurk!
推到 Facebook!

有關FTP取回檔案資訊的問題

缺席
00156
高階會員


發表:45
回覆:195
積分:112
註冊:2002-06-01

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-01-19 15:28:55 IP:61.56.xxx.xxx 未訂閱
請教諸位先進: 利用IdFTP元件的List方法取回的檔案資訊,要如何分解為檔名、修改日期、檔案大小等屬性? 試了幾個Server,取回的資訊格式有點混亂,不知道有沒有特定規則? 謝謝各位!
cmf
尊榮會員


發表:84
回覆:918
積分:1032
註冊:2002-06-26

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-01-20 09:35:18 IP:61.218.xxx.xxx 未訂閱
引言: 請教諸位先進: 利用IdFTP元件的List方法取回的檔案資訊,要如何分解為檔名、修改日期、檔案大小等屬性? 試了幾個Server,取回的資訊格式有點混亂,不知道有沒有特定規則? 謝謝各位!
TidFTP.LIST //取的檔案 及 目錄 清單 procedure List(ADest: TStrings; const ASpecifier: string; const ADetails: boolean); ADest: TStrings; //讀取 目前目錄 之 檔案 及 子目錄 清單 const ASpecifier: string = ''; //File mask for the listing. Default value is ''. // 例: '*.txt' const ADetails: boolean = true //Include file details. Default value is True. Description List is a procedure used to request a list of files or directories in the current directory on the FTP server. ADest is the TStringList used to store the information requested. ASpecifier is a String that contains a mask indicating the files and/or directories to be included in the listing. ASpecifier can contain common wildcard characters like '*' and '?'. Some useful masks include: *.* - All files in the current directory. * - All directory entries in the current directory. *. - All files regardless of extension in the current directory. A??.txt - All text files that have a 3-character name starting with 'A'. ADetails is a Boolean that indicates if the list should contain details about the files and directories that match the mask in ASpecifier. When ADetails is False, only the file or directory name is returned in the ADest string list. When ADetails is True, List can return FTP server-dependent details including the file size, date modified, and file permissions for the Owner, Group, and User. An application must be able to parse the detailed list format based on the FTP server type identified in SystemDesc.
------
︿︿
00156
高階會員


發表:45
回覆:195
積分:112
註冊:2002-06-01

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-01-20 16:13:57 IP:61.56.xxx.xxx 未訂閱
謝謝cmf... 這段說明我已經看過了,也能夠取回檔案資訊。只是取回後的格式不知道該如何分解。例如:
  • drwxr-xr-x 2 pchome home 4096 Jan 19 02:16 jp
  • -rw-rw-r-- 1 53 53 14808 Jan 18 2002 news.html
  • 01-06-03 03:02PM nav
都是我取回的(來自不同網站),我想知道這些取回的資料格式有沒有一定規範?
cmf
尊榮會員


發表:84
回覆:918
積分:1032
註冊:2002-06-26

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-01-20 16:28:35 IP:61.218.xxx.xxx 未訂閱
procedure TMainForm.ChageDir(DirName: String); begin   try   SetFunctionButtons(false);   IdFTP1.ChangeDir(DirName);   IdFTP1.TransferType := ftASCII;      CurrentDirEdit.Text := IdFTP1.RetrieveCurrentDir;      {Panel3.Caption := 'Current directory is: ' + IdFTP1.RetrieveCurrentDir +   '  Remote system is ' + IdFTP1.SystemDesc;}   DirectoryListBox.Items.Clear;   IdFTP1.List(DirectoryListBox.Items);   finally   SetFunctionButtons(true);   end; end;        procedure TMainForm.DirectoryListBoxDblClick(Sender: TObject); Var   Name, Line: String;   IsDirectory: Boolean; begin   if not IdFTP1.Connected then exit;   Line := DirectoryListBox.Items[DirectoryListBox.ItemIndex];   Name := GetNameFromDirLine(Line, IsDirectory);   if IsDirectory then begin   // Change directory   SetFunctionButtons(false);   ChageDir(Name);   SetFunctionButtons(true);   end   else begin   try   SaveDialog1.FileName := Name;   if SaveDialog1.Execute then begin   SetFunctionButtons(false);   IdFTP1.TransferType := ftBinary;   BytesToTransfer := IdFTP1.Size(Name);   IdFTP1.Get(Name, SaveDialog1.FileName, true);   end;   finally   SetFunctionButtons(true);   end;   end; end;        function GetNameFromDirLine(Line: String; Var IsDirectory: Boolean): String; Var   i: Integer;   DosListing: Boolean; begin   IsDirectory := Line[1] = 'd';   DosListing := false;   for i := 0 to 7 do begin   if (i = 2) and not IsDirectory then begin   IsDirectory := Copy(Line, 1, Pos(' ', Line) - 1) = ''; if not IsDirectory then DosListing := Line[1] in ['0'..'9'] else DosListing := true; end; Delete(Line, 1, Pos(' ', Line)); While Line[1] = ' ' do Delete(Line, 1, 1); if DosListing and (i = 2) then break; end; Result := Line; end;
------
︿︿
00156
高階會員


發表:45
回覆:195
積分:112
註冊:2002-06-01

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-01-21 11:34:14 IP:61.56.xxx.xxx 未訂閱
嗯...不知道是不是少掉什麼,cmf的程式碼沒辦法runㄝ... 我把現有的資料分析,做出下面的結論,不知道有沒有錯(網上實在找不到這方面的文件):
  • FTP Server若是UNIX系統,取回檔案格式欄位為
    [檔案屬性] [?] [?] [?] [Size] [月] [日] [年或時:分] [檔名]
  • FTP Server若是Windows NT系統,取回檔案格式欄位為
    [月-日-年] [時:分(AM/PM)] [〈DIR〉或Size] [檔名]
各欄位以空格分開。其中UNIX上傳回第8欄有時是[年份],有時是[時:分],很奇怪。 下面是我根據上面的分析寫的code,請各位前輩指點...
//定義伺服器種類、檔案屬性、檔案資訊等型態
type TFTPServerType = (ftpUnix, ftpWindows, ftpUnknow);    type TFTPFileType = (ffDirectory, ffFile, ffUnknow);    type
  TFTPFileInfo = record
    Name:TFileName;
    Size:longint;
    Attr:TFTPFileType;
    year:word;
    month,dat,hr,min:byte;
  end;
//解析的函數
function GetAStr(_OStr:string;_no:byte;_IDStr:string):string; {字串分解工具}
var i_:word;
    beforeCk_,currentCk_:boolean;
    timeOfChange_:word;
 function isID(_xch:char):boolean;
 begin
   if Pos(_xch,_IDStr)>0 then Result:=true else Result:=false;
 end;
begin
  Result:='';
  beforeCk_:=true;
  timeOfChange_:=0;
  i_:=0;
  repeat
    Inc(i_);
    currentCk_:=isID(_OStr[i_]);
    if (beforeCk_ xor currentCk_) then Inc(timeOfChange_);
    if timeOfChange_=(_no*2-1) then
      Result:=Result _OStr[i_];
    beforeCk_:=currentCk_;
  until ((timeOfChange_=(_no*2)) or (i_=Length(_OStr)));
end;
function GetServerType(const ServerEntry:string):TFTPServerType; {取得FTP Server類型}
begin
  if Pos('UNIX',UpperCase(ServerEntry))>0 then Result:=ftpUnix
  else if Pos('WINDOWS',UpperCase(ServerEntry))>0 then Result:=ftpWindows
  else Result:=ftpUnknow;
end;
function GetMonthNum(MonthStr:string):byte; {僅供procedure DecodeFileInfo使用}
const MonthLst = 'JAN_FEB_MAR_APR_MAY_JUN_JUL_AUG_SEP_OCT_NOV_DEC_';
var i:byte;
begin
  i:=Pos(UpperCase(MonthStr) '_',MonthLst);
  if i>0 then Result:=Trunc((i-1)/4) 1 else Result:=0;
end;
procedure DecodeFileInfo(ServerType:TFTPServerType; AFileEntry:string; var FI:TFTPFileInfo); {解析Server傳回的內容}
var s_:string[64];
    y_,m_,d_:word;
begin
  case ServerType of
    ftpUnix:
      begin
        //FI.Name:=GetAStr(AFileEntry,9,' ');
        FI.Name:=Copy(AFileEntry,56,Length(AFileEntry)-55);            FI.Size:=StrToIntDef(GetAStr(AFileEntry,5,' '),0);
        FI.month:=GetMonthNum(GetAStr(AFileEntry,6,' '));
        FI.dat:=StrToIntDef(GetAStr(AFileEntry,7,' '),0);
        s_:=GetAStr(AFileEntry,8,' ');
        if Pos(':',s_)>0 then
          begin //時:分
            FI.year:=CurrentYear;
            FI.hr:=StrToIntDef(GetAStr(s_,1,':'),0);
            FI.min:=StrToIntDef(GetAStr(s_,2,':'),0);
            DecodeDate(Date,y_,m_,d_);
            if m_-1 then
          begin
            if (FI.year 2000)>CurrentYear then FI.year:=FI.year 1900
            else FI.year:=FI.year 2000;
          end;
        s_:=GetAStr(AFileEntry,2,' ');
        FI.hr:=StrToIntDef(Copy(s_,1,2),0);
        FI.min:=StrToIntDef(Copy(s_,4,2),0);
        if ((UpCase(s_[6])='P') and (FI.hr<12)) then Inc(FI.hr,12); //for PM to 24H
        if UpperCase(GetAStr(AFileEntry,3,' '))='' then //目錄格式
          begin
            FI.Attr:=ffDirectory;
            FI.Size:=0;
          end
        else //檔案格式
          begin
            FI.Attr:=ffFile;
            FI.Size:=StrToIntDef(GetAStr(AFileEntry,3,' '),0);
          end;
      end;
  end;
end;    
發表人 - 00156 於 2003/01/21 13:41:34 發表人 - 00156 於 2003/02/02 15:02:07
turboted
版主


發表:95
回覆:754
積分:452
註冊:2002-07-23

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-01-31 14:06:11 IP:61.216.xxx.xxx 未訂閱
就我以前的經驗來看 其實,不同的ftp server 回傳的info 多少會一些差異 我建議您可以support 幾個比較大的server 就夠了
00156
高階會員


發表:45
回覆:195
積分:112
註冊:2002-06-01

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-02-02 15:07:34 IP:61.56.xxx.xxx 未訂閱
謝謝cmf、turboted兩位前輩的指點,我會設法繼續取得相關文件來修正上面的程式碼。 大家新年快樂唷~
系統時間:2024-04-18 17:55:34
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!