Linux操作系統—文件(3)
分類:Linux操作系統
文件屬性的修改
改變文件的所有者
使用chown系列函數可以改變文件的所有者,同時還可以改變文件的所屬組。這些函數的原型如下:
#include <sys/types.h>
#include <unistd.h>
int chown(const char *path, uid_t owner, gid_t group);
int fchown(int fd, uid_t owner, gid_t group);
int lchown(const char *path, uid_t owner, git_t group);
成功時返回0,失敗時返回-1
chown和lchown的區別:當一個文件是一個符號連接時,lchown改變的是該符號連接本身的所有者,而chown改變的是該連接指向的文件的所有者。
因爲涉及到了管理權限的問題,只有root用戶纔可以使用這些函數來改變任意文件的所有者和所屬組,而普通用戶只能改變屬於自己的文件的所屬組,並且指定的所屬組只能是用戶自身所在組之一。
改變文件的訪問權限
使用chmod系列函數可以改文件的訪問權限
#include <sys/types.h>
#include <sys/stat.h>
int chmod(const char *pathname, modt_t mode);
int fchmod(int fd, modt_t mode);
其中mode爲文件的權限。一般由一組八進制數進行二進制“或”運算構成,其中的各個位表示一種權限,稱爲權限位,如下:
權限位 | 八進制常量 | 含義 |
---|---|---|
S_ISUID | 04000 | 設置SUID |
S_ISGID | 02000 | 設置SGID |
S_ISVTX | 01000 | 設置粘滯位 |
S_IRUSR | 00400 | 文件所有者可讀 |
S_IWUSR | 00200 | 文件所有者可寫 |
S_IXUSR | 00100 | 文件所有者可執行 |
S_IRGRP | 00040 | 文件所屬組可讀 |
S_IWGRP | 00020 | 文件所屬組可寫 |
S_IXGRP | 00010 | 文件所屬組可執行 |
S_IROTH | 00004 | 其它用戶可讀 |
S_IWOTH | 00002 | 其它用戶可寫 |
S_IXOTH | 00001 | 其它用戶可執行 |
成功時返回0,出錯返回-1
重命名文件
普通文件和目錄文件均可以使用rename函數重命名,該函數原型如下:
#include <stdio.h>
int rename(const char *oldpath, const char *newpath);
複製文件描述符
複製文件描述符需要用到dup或dup2函數,這兩個函數常用於重定向一個已打開的文件描述符。其原型如下:
#include <unistd.h>
int dup(int oldfd);
int dup2(int oldfd, int newfd);
這兩個函數都將返回複製後的文件描述符,不同的是,dup函數返回的是最小未用的文件描述符,而dup2函數返回的是預先指定的文件描述符newfd。如果newfd正在使用,則會先關閉newfd。但如果newfd與oldfd一樣,則關閉文件正常返回。
上鎖和解鎖文件
Linux下可以調用flock函數來上鎖或解鎖一個文件。該函數原型如下:
#include <sys/file.h>
int flock(int fd, int operaation);
函數各參數和返回值含義如下:
- fd:文件描述符
- operation:上鎖或解鎖方式,可取以下值之一
- LOCK_SH:共享鎖
- LOCK_EX:獨佔鎖
LOCK_UN:解鎖
返回值:成功時返回0,失敗時返回-1
一個進程對一個文件只能有一個獨佔鎖,但可以有多個共享鎖。上鎖的作用只有在別的進程要對該文件上鎖時才能表現出來。如果一個進程不試圖去上鎖一個已經被上鎖的文件,就不應該對其進行訪問。
應當注意:對文件的操縱本身與鎖並沒有什麼關係。無論文件是否被上鎖,用戶都可以隨便對文件進行正常情況下的任何操作。上鎖文件的目的是爲了同步多個進程之間的操作,參與同步的各進程必須遵守約定的規則,上鎖纔有意義。
默認情況下,flock是阻塞式的。也就是說,如果另一個進程已持有該文件的鎖且該鎖與本進程請求的鎖不兼容,flock將會阻塞,直到擁有該文件的鎖的進程對其解鎖爲止。如果要進行非阻塞式調用。應將operation參數與常量”LOCK_NB”進行二進制”或“操作後再傳遞給flock函數。非阻塞式調用flock後,flock會立即返回-1, 並且errno的值將爲EWOULDBLOCK。
創建硬鏈接
調用link函數可以對一個已經存在的文件建立新的鏈接
#include <unistd.h>
int link(const char *oldpath, const char *newpath);
使用link創建的新的鏈接文件和原文件是一模一樣的,地位是對等的,它們都指向相同的文件。創建之後,就沒有必要也無法區分哪個是原始文件了。
創建和讀取符號鏈接
#include <unistd.h>
int symlink(const char *oldpath, const char *newpath);
注意:符號鏈接文件的權限和原文件的權限是無關的
讀取符號鏈接
讀取符號鏈接所指向的目標文件需要使用系統調用readlink函數,該函數原型如下:
#include <unistd.h>
ssize_t readlink(const char *path, char *buf, size_t bufsize);
函數各參數和返回值的含義如下:
- path:符號鏈接文件名
- buf:用於存儲獲取到的信息的緩衝區
- bufsize:緩衝區大小
- 返回值:若成功爲實際寫入緩衝區的字節數;若出錯爲-1,錯誤記錄在errno
刪除鏈接
要刪除鏈接,包括硬鏈接和符號鏈接,可通過系統調用unlink函數實現,該函數原型如下:
#include <unistd.h>
int unlink(const char *pathname);
目錄文件的操作
目錄文件的創建
創建目錄文件使用mkdir函數,該函數原型如下:
#include <sys/stat.h>
#include <sys/types.h>
int mkdir(const char *pathname, mode_t mode);
各參數和返回值含義如下:
pathname:新建的目錄文件名
mode:存取許可權位,由下列一個或多個常數進行或運算構成。最終權限受系統變量umask限制
- S_IRUSR:文件所有者讀
- S_IWUSR:文件所有者寫
- S_IXUSR:文件所有者執行
- S_IRGRP:組用戶可讀
- S_IWGRP:組用戶可寫
- S_IXGRP:組用戶可執行
- S_IROTH:其它用戶可讀
- S_IWOTH:其它用戶可寫
- S_IXOTH:其它用戶可執行
目錄文件的刪除
#include <unistd.h>
int rmdir(const char *pathname);
注意:使用rmdir函數只能刪除空的目錄,如果pathname所指定的目錄中含有文件,則函數調用將失敗
目錄的打開和關閉
打開目錄文件
&emap; 打開目錄文件可使用opendir函數(非系統調用),原型如下:
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);
函數調用成功則返回指向目錄文件的結構指針;若出錯爲NULL,錯誤記錄在errno中
如果opendir函數執行成功會返回一個目錄流(directory stream),該流定位在目錄塊的第一項。
關閉目錄文件
#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *drip);
函數各參數和返回值的含義如下:
dirp:已打開的目錄流
返回值:成功返回0,出錯返回-1
目錄文件的讀取
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
函數各參數和返回值含義如下:
返回值:若成功爲下一個目錄項的指針;若已達到目錄流末尾則返回NULL且errno值不變;若出錯爲NULL,錯誤記錄值記錄在errno中
函數返回的結構體類型如下:
struct dirent{
ino_t d_ino; //索引節點
off_t d_off; //下一目錄項的位移量
unsigned short d_reclen; //本記錄的長度
unsigned char d_type; //文件類型
char d_name[256]; //文件名
}