C語言目錄和文件操作擴展

本章節擴展一些目錄和文件操作的更多知識,因爲這些知識涉及到時間操作,所以放在時間操作之後的章節中介紹。

一、access庫函數

access函數用於判斷當前操作系統用戶對文件或目錄的存取權限。

包含頭文件:

#include <unistd.h>

函數聲明:

int access(const char *pathname, int mode);

參數說明:

pathname文件名或目錄名,可以是當前目錄的文件或目錄,也可以列出全路徑。

mode 需要判斷的存取權限。在頭文件unistd.h中的預定義如下:

#define R_OK 4     // R_OK 只判斷是否有讀權限
#define W_OK 2    // W_OK 只判斷是否有寫權限
#define X_OK 1     // X_OK 判斷是否有執行權限
#define F_OK 0     // F_OK 只判斷是否存在

返回值:

當pathname滿足mode的條件時候返回0,不滿足返回-1。

在實際開發中,access函數主要用於判斷文件或目錄是否是存在。

二、stat庫函數

1、stat結構體

struct stat結構體用於存放文件和目錄的狀態信息,如下:

struct stat
{
  dev_t st_dev;   // device 文件的設備編號
  ino_t st_ino;   // inode 文件的i-node
  mode_t st_mode;   // protection 文件的類型和存取的權限
  nlink_t st_nlink;   // number of hard links 連到該文件的硬連接數目, 剛建立的文件值爲1.
  uid_t st_uid;   // user ID of owner 文件所有者的用戶識別碼
  gid_t st_gid;   // group ID of owner 文件所有者的組識別碼
  dev_t st_rdev;  // device type 若此文件爲設備文件, 則爲其設備編號
  off_t st_size;  // total size, in bytes 文件大小, 以字節計算
  unsigned long st_blksize;  // blocksize for filesystem I/O 文件系統的I/O 緩衝區大小.
  unsigned long st_blocks;  // number of blocks allocated 佔用文件區塊的個數, 每一區塊大小爲512 個字節.
  time_t st_atime;  // time of lastaccess 文件最近一次被存取或被執行的時間, 一般只有在用mknod、 utime、read、write 與tructate 時改變.
  time_t st_mtime;  // time of last modification 文件最後一次被修改的時間, 一般只有在用mknod、 utime 和write 時纔會改變
  time_t st_ctime;  // time of last change i-node 最近一次被更改的時間, 此參數會在文件所有者、組、 權限被更改時更新
};

struct stat結構體的成員變量比較多,對程序員來說,重點關注st_mode、st_size和st_mtime成員就可以了。注意st_mtime是一個整數表達的時間,需要程序員自己寫代碼轉換格式。

st_mode成員的取值很多,或者使用如下兩個宏來判斷。

S_ISREG (st_mode) 是否爲一般文件 
S_ISDIR (st_mode) 是否爲目錄 

2、stat庫函數

包含頭文件:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

函數聲明:

int stat(const char *path, struct stat *buf);

stat函數獲取path指定文件或目錄的信息,並將信息保存到結構體buf中,執行成功返回0,失敗返回-1。

示例(book145.c)

/*
 * 程序名:book145.c,此程序演示目錄和文件的存取權限和狀態信息
 * 作者:C語言技術網(www.freecplus.net) 日期:20190525
*/
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

// 本程序運行要帶一個參數,即文件或目錄名
int main(int argc,char *argv[])
{
  if (argc != 2)  { printf("請指定目錄或文件名。\n"); return -1; }

  if (access(argv[1],F_OK) != 0) { printf("文件或目錄%s不存在。\n",argv[1]); return -1; }

  struct stat ststat;

  // 獲取文件的狀態信息
  if (stat(argv[1],&ststat) != 0) return -1;

  if (S_ISREG(ststat.st_mode)) printf("%s是一個文件。\n",argv[1]);
  if (S_ISDIR(ststat.st_mode)) printf("%s是一個目錄。\n",argv[1]);
}

運行效果

在這裏插入圖片描述

三、utime庫函數

utime函數用於修改文件的存取時間和更改時間。

包含頭文件:

#include <utime.h>

函數聲明:

int utime(const char *filename, const struct utimbuf *times);

函數說明:utime()用來修改參數filename 文件所屬的inode存取時間。如果參數times爲空指針(NULL),
則該文件的存取時間和更改時間全部會設爲目前時間。結構utimbuf 定義如下:

struct utimbuf
{
  time_t actime;
  time_t modtime;
};

返回值:執行成功則返回0,失敗返回-1。

四、rename庫函數

rename函數用於重命名文件或目錄,相當於操作系統的mv命令,對程序員來說,在程序中極少重命名目錄,但重命名文件是經常用到的功能。

包含頭文件:

#include <stdio.h>

函數聲明:

int rename(const char *oldpath, const char *newpath);

參數說明:

oldpath 文件或目錄的原名。

newpath 文件或目錄的新的名稱。

返回值:0-成功,-1-失敗。

五、remove庫函數

remove函數用於刪除文件或目錄,相當於操作系統的rm命令。

包含頭文件:

#include <stdio.h>

函數聲明:

int remove(const char *pathname);

參數說明:

pathname 待刪除的文件或目錄名。

返回值:0-成功,-1-失敗。

六、課後作業

1)繼續豐富您的函數庫,用mkdir創建目錄的時候,例如mkdir("/tmp/aaa/bbb/ccc",0755);,如果上級目錄不存在(/tmp/aaa或/tmp/aaa/bbb不存在),是無法創建/tmp/aaa/bbb/ccc目錄的,這不是程序員想要的,我們要再寫一個函數,如果上級目錄不存在,就創建上級目錄,一級一級的創建,函數的聲明如下:

int MKDIR(const char *pathname);

2)編寫一個獲取文件時間的函數,聲明如下:

// 獲取文件的時間,即modtime
void FileMTime(const char *in_FullFileName,char *out_ModTime);

out_ModTime的格式是"yyyy-mm-dd hh24:mi:ss"。

3)編寫一個獲取文件大小的函數,聲明如下:

// 獲取文件的大小,返回字節數
int FileSize(const char *in_FullFileName);

4)rename函數有一個不足,如果目標文件名目錄newpath的上級目錄不存在,函數返回失敗,重寫一個新的RENAME函數,如果newpath的上級目錄不存在,先創建newpath的上級目錄,再rename,函數的聲明如下:

int RENAME(const char *oldpath, const char *newpath);

5)utime函數的第二個參數是一個結構體utimbuf,不方便使用,在實際開發中,我們更希望是一個字符串格式的時間,如:"2019-02-08 12:05:02",重寫一個utime函數,功能與utime相同,但是把第二個參數改爲字符串格式的時間,函數的聲明如下:

int UTIME(const char *filename, const char *strtime);

七、版權聲明

C語言技術網原創文章,轉載請說明文章的來源、作者和原文的鏈接。
來源:C語言技術網(www.freecplus.net)
作者:碼農有道

如果這篇文章對您有幫助,請點贊支持,或在您的博客中轉發我的文章,謝謝!!!
如果文章有錯別字,或者內容有錯誤,或其他的建議和意見,請您留言指正,非常感謝!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章