1. 程式人生 > >c++/C 獲得檔案的屬性檔案真實修改之後再更新記憶體

c++/C 獲得檔案的屬性檔案真實修改之後再更新記憶體

【Kenmark】:
http://topic.csdn.net/t/20021127/11/1209086.html
http://topic.csdn.net/t/20020613/19/801649.html
http://topic.csdn.net/t/20020918/09/1032607.html

【nevergone】:
GetFileAttributes

【Kenmark】:
C和C++的都有還有MFC的~

【Chiyer】:
GetFileAttribute

【jixingzhong】:
函式名: stat 
功  能: 讀取開啟檔案資訊 
用  法: int stat(char *pathname, struct stat *buff); 
程式例: 

#include <sys\stat.h> 
#include <stdio.h> 
#include <time.h> 

#define FILENAME "TEST.$$$" 

int main(void) 

   struct stat statbuf; 
   FILE *stream; 

   /* open a file for update */ 
   if ((stream = fopen(FILENAME, "w+")) == NULL) 
   { 
      fprintf(stderr, "Cannot open output file.\n"); 
      return(1); 
   } 

   /* get information about the file */ 
   stat(FILENAME, &statbuf); 

   fclose(stream); 

   /* display the information returned */ 
   if (statbuf.st_mode & S_IFCHR) 
      printf("Handle refers to a device.\n"); 
   if (statbuf.st_mode & S_IFREG) 
      printf("Handle refers to an ordinary file.\n"); 
   if (statbuf.st_mode & S_IREAD) 
      printf("User has read permission on file.\n"); 
   if (statbuf.st_mode & S_IWRITE) 
      printf("User has write permission on file.\n"); 

   printf("Drive letter of file: %c\n", 'A'+statbuf.st_dev); 
   printf("Size of file in bytes: %ld\n", statbuf.st_size); 
   printf("Time file last opened: %s\n", ctime(&statbuf.st_ctime)); 
   return 0; 
}

【jixingzhong】:
通常使用 win API 是比較合適的【在win系統下】

【Chiyer】:
這樣也可以

win32_find_data   filestruct;   
        handle   hf;   
        hf   =   findfirstfile(檔名.c_str(),   &filestruct);   
    
  filestruct.ftcreationtime//建立時間   
  filestruct.ftlastaccesstime//訪問時間   
  filestruct.ftlastwritetime//修改時間   
    
  findclose(hf);

【jixingzhong】:
【Ref: http://developer.51cto.com/art/200511/10951.htm】

在VC++下對檔案屬性的獲取與更改
作者: 出處:51cto.com整理  ( 7 ) 磚  ( 5 ) 好  評論 ( 0 ) 條  進入論壇 
更新時間:2005-11-08 11:01
關 鍵 詞:C
閱讀提示:本文講述了在Visual C++ 下程式設計實現對磁碟檔案的屬性進行獲取以及更改的一般方法,並給出部分相關的關鍵程式碼 
一、 引言 

檔案是資料在磁碟上最常用的一種存放形式,也是在程式設計中與之經常打交道的一種程式設計物件,不少程式尤其是資料傳輸和處理類的應用程式更是需要頻繁的建立、讀取和寫入檔案。對於一些要求不是很嚴格的程式,我們往往只關心檔案的內容是否正確、檔案大小是否有增減或是再嚴格一些,看檔名是否符合規定等等。以上這些要素對於大多數程式而言顯然是可以滿足實際需求的,但對於某些特殊行業的一些有著比較嚴格要求的軟體系統,僅有以上要素還是遠遠不夠的,往往還需要對檔案的所有屬性諸如檔案的建立時間、檔案的最後訪問時間、檔案的最後修改時間等等進行提取處理與重新設定。 

二、 WIN32_FIND_DATA結構 

關於檔案的全部屬性資訊,總計有以下以下9種:檔案的標題名、檔案的屬性(只讀、存檔,隱藏等)、檔案的建立時間、檔案的最後訪問時間、檔案的最後修改時間、檔案大小的高位雙字、檔案大小的低位雙字、保留、保留。在這裡只有檔案標題名和檔案的長度可以通過CFile類比較方便的獲得,而對於其他幾種屬性的獲取和設定就無能為力了。 

在用findfirst()和findnext()函式去查詢磁碟檔案時經常使用的一個數據結構WIN32_FIND_DATA的成員變數裡包含了以上所有的檔案屬性,因此可以通過這個結構作為獲取和更改檔案屬性的手段。該結構的內容如下: 

typedef struct _WIN32_FIND_DATA { 

DWORD dwFileAttributes; //檔案屬性 

FILETIME ftCreationTime; // 檔案建立時間 

FILETIME ftLastAccessTime; // 檔案最後一次訪問時間 

FILETIME ftLastWriteTime; // 檔案最後一次修改時間 

DWORD nFileSizeHigh; // 檔案長度高32位 

DWORD nFileSizeLow; // 檔案長度低32位 

DWORD dwReserved0; // 系統保留 

DWORD dwReserved1; // 系統保留 

TCHAR cFileName[ MAX_PATH ]; // 長檔名 

TCHAR cAlternateFileName[ 14 ]; // 8.3格式檔名 

} WIN32_FIND_DATA, *PWIN32_FIND_DATA; 

可以通過FindFirstFile()函式根據當前的檔案存放路徑查詢該檔案來把待操作檔案的相關屬性讀取到WIN32_FIND_DATA結構中去: 

WIN32_FIND_DATA ffd ; 

HANDLE hFind = FindFirstFile("c:\\test.dat",&ffd); 

在使用這個結構時不能手工修改這個結構中的任何資料,結構對於開發人員來說只能作為一個只讀資料,其所有的成員變數都會由系統完成填寫。在MSDN幫助中可以查詢到關於WIN32_FIND_DATA結構的更加詳細的說明。 

三、 檔案屬性資訊的獲取與更改 

為了更好的儲存獲取到的檔案屬性資訊,對應於檔案屬性構造一個自定義的FILE_INFO資料結構,獲取的屬性資訊可暫存於此: 

typedef struct _FILE_INFO { 

TCHAR szFileTitle[128]; //檔案的標題名 

DWORD dwFileAttributes; //檔案的屬性 

FILETIME ftCreationTime; //檔案的建立時間 

FILETIME ftLastAccessTime; //檔案的最後訪問時間 

FILETIME ftLastWriteTime; //檔案的最後修改時間 

DWORD nFileSizeHigh; //檔案大小的高位雙字 

DWORD nFileSizeLow; //檔案大小的低位雙字 

DWORD dwReserved0; //保留,為0 

DWORD dwReserved1; //保留,為0 

} FILE_INFO, * PFILE_INFO; 

首先用FindFirstFile()函式將檔案屬性獲取到WIN32_FIND_DATA 結構物件FindFileData中去,之後可以用FindClose()將其關閉,並把FindFileData中的有關檔案屬性資訊的內容複製到自定義結構FILE_INFO的結構物件FileInfo中備用。下面是關於這部分描述的部分關鍵程式碼: 

//宣告結構物件 

FILE_INFO FileInfo; 

WIN32_FIND_DATA FindFileData; 

…… 

//獲取檔案屬性資訊 

FindClose(FindFirstFile("Test.txt",&FindFileData)); 

memset(&FileInfo,0,sizeof(FILE_INFO)); 

…… 

//將檔案屬性資訊儲存到FileInfo中備用 

strcpy(FileInfo.szFileTitle,myFile.GetFileTitle()); 

FileInfo.dwFileAttributes = FindFileData.dwFileAttributes; 

FileInfo.ftCreationTime = FindFileData.ftCreationTime; 

FileInfo.ftLastAccessTime = FindFileData.ftLastAccessTime; 

FileInfo.ftLastWriteTime = FindFileData.ftLastWriteTime; 

FileInfo.nFileSizeHigh = FindFileData.nFileSizeHigh; 

FileInfo.nFileSizeLow = FindFileData.nFileSizeLow; 

…… 

在獲取到檔案的原始屬性資訊後既可以原封不動的將屬性重新寫到檔案,也可以對其中某一項或某幾項屬性內容進行修改後再行寫入檔案,從而達到更改檔案屬性的目的。比如可以用SetFileTime()函式設定檔案的建立時間、最近一次訪問時間以及最近一次修改的時間等等: 

SetFileTime((HANDLE)destFile.m_hFile, //待寫入的檔案控制代碼 

&FileInfo.ftCreationTime, //檔案的建立時間 

&FileInfo.ftLastAccessTime, //檔案最近一次的訪問時間 

&FileInfo.ftLastWriteTime); //檔案最近一次的修改時間 

也可以用SetFileAttributes() 函式實現對檔案屬性的修改: 

SetFileAttributes(FileInfo.szFileTitle,FileInfo.dwFileAttributes); 

至於檔名的修改則更加簡單,直接在建立檔案時在CreateFile()或CFile類的成員函式Open裡直接對檔名引數進行設定即可。 

小結:本文通過對WIN32_FIND_DATA結構和SetFileTime()、SetFileAttributes()等主要函式實現了對磁碟檔案的相關屬性資訊的獲取與修改。用此技術可以在通訊等對檔案有嚴格要求的應用領域實現檔案全部資訊(包括檔案內容、檔名以及檔案屬性等)的完整傳送。本文所述程式在Windows 98下由Microsoft Visual C++ 6.0編譯除錯通過。

【jixingzhong】:
unix 系統下:

【Ref:http://www.tongyi.net/os/unix/1055532.html】
如何在程式中獲得檔案的屬性。這裡需要用到三個函式,它們的定義是:
       #include <sys/types.h>
       #include <sys/stat.h>
 
       int stat(const char* pathname, struct stat* buf);  //成功則返回0,失敗返回-1
       int fstat(int fd, struct stat* buf);                  //成功則返回0,失敗返回-1
       int lstat(const char* pathname, struct stat* buf); //成功則返回0,失敗返回-1
       
  stat()函式接收一個檔名,返回該檔案的stat結構。fstat()接收一個已開啟的檔案描述符,返回該檔案的stat結構。lstat()與stat()類似,但對於符號連結,它返回該符號連結的stat結構,而不是該符號連結所引用檔案的stat結構。stat結構是一包含了檔案所有屬性資訊的結構,它的定義如下:
       
       struct stat{
           mode_t  st_mode;   //file type & mode
           ino_t   st_ino;    //i-node number
           dev_t   st_dev;    //device number
           dev_t   st_rdev;   //device number for special files
           nlink_t st_nlink;  //number of links
           uid_t   st_uid;    //user ID of owner
           gid_t   st_gid;    //group ID of owner
           off_t   st_size;   //size in bytes,for regular files
           time_t  st_atime;  //time of last access
           time_t  st_mtime;  //time of last modification
           time_t  st_ctime;  //time of last file status change
           long    st_blksize;//best I/O block size
           long    st_blocks; //number of 512 bytes blocks allocated
       };
       
  stat結構中最常用到的屬性是st_mode(檔案的型別及檔案的訪問許可權)、st_nlink(硬連結數,表示有幾個連結到該檔案上)、st_uid、st_gid、st_size(以位元組為單位的檔案長度,只對普通檔案、目錄檔案和符號連線有意義)、st_atime、st_mtime、st_ctime。
       我們曾一再提到Unix系統中一切皆可視為檔案,不過細而化之的話又可以分為多種型別,那麼在程式中如何去對檔案型別進行判別呢?這就需要用到下表中所示的一些巨集:
       
巨集 作用 
S_ISREG() 測試是否為普通檔案 
S_ISDIR() 測試是否為目錄檔案 
S_ISCHR() 測試是否為字元特殊檔案 
S_ISBLK() 測試是否為塊特殊檔案 
S_ISFIFO() 測試是否為FIFO檔案 
S_ISLNK() 測試是否為連結檔案 
S_ISSOCK() 測試是否為socket檔案 
S_ISUID() 測試是否設定了“設定-使用者-ID”位 
S_ISGID() 測試是否設定了“設定-組-ID”位 

       
  [程式6]
      
  #include <stdio.h>
  #include <stdlib.h>
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <fcntl.h>
  #include <unistd.h>
 
  int main(int argc, char * argv[])
       {
    int i;
    struct stat buf;
    char *ptr;
    for(i=1; i< argc; i++)
    {
        printf("%s: ", argv[i]);
      if(lstat(argv[i],&buf)<0)
      {
                     printf("lstat error.");
                     continue;
      }
      if(S_ISREG(buf.st_mode)) ptr = "regular";
      else if(S_ISDIR(buf.st_mode)) ptr = "directory";
      else if(S_ISCHR(buf.st_mode)) ptr = "char special";
      else if(S_ISBLK(buf.st_mode)) ptr = "block special";
      else if(S_ISFIFO(buf.st_mode)) ptr = "fifo";
      else ptr = "Others";
      printf(" %s\n",ptr );
    }
    return 0;
  }
       
  編譯程式後,我們先來使用命令mkfifo myfifo.pipe建一個管道檔案,然後執行:
       filetype myfifo.pipe . /etc/passwd
       螢幕會顯示: 
         myfifo.pipe : fifo    
       . : directory
       /etc/passwd : regular
      
  此外,st_mode屬性還包含了可用於對檔案的屬主及許可權進行判斷的巨集,如下表所示:    
        
巨集 意義 
S_IRUSR 所有者-讀 
S_IWUSR 所有者-寫 
S_IXUSR 所有者-執行 
S_IRGRP 組-讀 
S_IWGRP 組-寫 
S_IXGRP 組-執行 
S_IROTH 其他-讀 
S_IWOTH 其他-寫 
S_IXOTH 其他-執行 

    
  [程式7]
 
       #include <iostream>
       #include <unistd.h>
       #include <sys/types.h>
       #include <sys/stat.h>
       using namespace std;
       int main()
       {
              cout << " enter a file name: ";
              char name[255];
              cin >> name;
              struct stat buf;
              if(lstat(name,&buf)<0)
              {
                     cout << " file not existing. " << endl;
                     return -1;
              }
              if(buf.st_mode & S_IRUSR) cout << " user can read|";
              if(buf.st_mode & S_IWUSR) cout << " user can write|";
              if(buf.st_mode & S_IXUSR) cout << " user can execute|";
              
              if(buf.st_mode & S_IRGRP) cout << " group can read|";
              if(buf.st_mode & S_IWGRP) cout << " group can write|";
              if(buf.st_mode & S_IXGRP) cout << " group can execute|";
       
              if(buf.st_mode & S_IROTH) cout << " other can read|";
              if(buf.st_mode & S_IWOTH) cout << " other can write|";
              if(buf.st_mode & S_IXOTH) cout << " ohter can execute|";
              cout << endl;
              return 0;
       }
       
       如果是想判斷某使用者對某一檔案的訪問許可權,則可呼叫access()函式,它的定義是:
       access(const char* path, int amode)
       其中,amode對應的值有R_OK(可讀)、W_OK(可寫)、X_OK(可執行)、F_OK(檔案存在)。