#Linux C 文件編程 ###文件操做 ####open
打開文件編程
header
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
函數
declare
int open(const char *path, int oflags);
int open(const char *path, int oflags, mode_t mode);
ui
args
path: 準備打開的文件或設備名字.
oflags: 指出要打開文件的訪問模式.操作系統
O_RDONLY [3選1] 只讀方式打開 O_WRONLY [3選1] 只寫方式打開 O_RDWR [3選1] 讀寫方式打開 O_APPEDN [可選] 追加方式打開 O_TRUNC [可選] 將文件長度設爲零, 丟棄以後內容. O_CREAT [可選] 按參數mode中給出的訪問模式建立文件. O_EXCL [可選] 和O_CREAT一塊兒用, 若是文件已存在, open調用失敗. O_NONBLOCK [可選] 非阻塞方式打開文件
mode: 用O_CREAT標誌的open來建立文件時賦予權限.指針
S_IRUSR 讀權限 文件屬主 S_IWUSR 寫權限 文件屬主 S_IXUSR 執行權 文件屬主 S_IRGRP 讀權限 文件屬組 S_IWGRP 寫權限 文件屬組 S_IXGRP 執行權 文件屬組 S_IROTH 讀權限 其餘用戶 S_IWOTH 寫權限 其餘用戶 S_IXOTH 執行權 其餘用戶 也能夠使用數字0777[全權限]來設置
return
success: fd 打開的文件描述符
error: -1 ####close
關閉文件 header
#include <unistd.h>
code
declare
int close(int fd);
遞歸
args
fd: 要關閉的文件描述符字符串
return
success:0 error: -1get
####read
讀取文件it
header
#include <unistd.h>
declare
size_t read(int fd, void *buf, size_t nbytes);
args
fd: 文件描述符
buf: 用來存儲讀入的數據的緩衝區
nbytes: 讀取的字符數
return
success: n 讀取的字符數
error: -1
####write
寫入文件 header
#include <unistd.h>
declare
size_t write(int fd, const void *buf, size_t nbytes);
args
fd: 文件描述符
buf: 待寫入的字符串
nbytes: 寫入的字符數
return
success: 寫入的字符數
error: -1
####lseek
設置文件描述符指針位置
header
#include <unistd.h>
#include <sys/types.h>
declare
off_t lseek(int fd, off_t offset, int whence);
args
fd: 文件描述符
off_set: 指定位置
whence: 參數定義該偏移值的用法
SEEK_SET: 文件頭的絕對位置 SEEK_CUR: 當前位置的相對位置 SEEK_END: 文件尾的相對位置
return
success: 返回文件到文件指針被設置處的字節偏移 error: -1
####stat
獲取文件元數據
header
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
declare
int fstat(int fd, struct stat *buf);
int stat(const char *path, struct stat *buf);
int lstat(const char *path, struct stat *buf);
lstat 經過文件路徑獲取軟連接文件元數據 stat 經過文件路徑獲取文件元數據 fstat 經過文件描述服來獲取文件元數據
args
fd: 文件描述符
path: 文件路徑
buf: 獲取文件元數據的結構體指針
return
success: 0
error: -1
####dup
複製文件描述符
header
#include <unistd.h>
declare
int dup(int fd);
int dup2(int fd,int fd2);
dup 根據fd返回一個新的文件描述符 dup2 明確指定描述符
args
fd: 文件描述符
fd2: 新文件描述符
return
success: 新文件描述符
error: -1
####getcwd
獲取當前工做目錄 header
#include <unistd.h>
declare
char* getcwd(char *buf, size_t size);
args
buf: 目錄路徑
size: buf空間大小
return
success: 指向工做目錄的指針
error: NULL
####chdir
改變當前目錄到指定目錄 header
#include <unistd.h>
declare
int chdir(const char *path);
args
path: 目錄路徑
return
success: 0
error: -1
####chroot
改變根目錄到指定目錄 header
#include <unistd.h>
declare
int chroot(const char *path);
args
path: 目錄路徑
return
success: 0
error: -1
####mkdir
建立目錄
header
#include <sys/stat.h>
#include <sys/types.h>
declare
int mkdir(const char *filename, mode_t mode);
args
filename: 目錄路徑
mode: 權限
return
success: 0
error: -1
####rmdir
刪除目錄
header
#include <unistd.h>
declare
int rmdir(const char *filename);
args
filename: 目錄路徑
return
success: 0
error: -1
####opendir
打開目錄
header
#include <sys/types.h>
#include <dirent.h>
declare
DIR *opendir(const char *path);
args
path: 路徑
return
success: DIR指針
error: NULL
####closedir
關閉目錄
header
#include <sys/types.h>
#include <dirent.h>
declare
int closedir(DIR *dir);
args
dir: DIR指針
return
success: 0
error: -1
####readdir
獲取目錄信息
header
#include <sys/types.h>
#include <dirent.h>
declare
struct dirent *readdir(DIR *dir);
args
dir: DIR指針
return
success: dirent結構體指針
error: NULL
###其餘操做
####chmod
改變文件/目錄權限 header
#include <sys/stat.h>
declare
int chmod(const char *path, mode_t mode);
args
path: 路徑
mode: 權限
return
success: 0
error: -1
####chown
改變文件/目錄屬主和屬組
header
#include <unistd.h>
declare
int chown(const char *path, uid_t owner, gid_t group);
args
path: 路徑
owner: 屬主
group: 屬組
return
success: 0
error: -1
####link
連接相關操做
header
#include <unistd.h>
declare
int link(const char *oldpath, const char *newpath);
int symlink(const char *oldpath, const char *newpath);
int unlink(const char * path );
link 硬連接一個文件 symlink 軟連接一個文件 unlink 刪除文件的一次硬連接[刪除文件]
args
oldpath: 被連接的文件
newpath: 新文件路徑
path: 路徑
return
success: 0
error: -1
####umask
改變文件/目錄權限掩碼 header
#include <sys/stat.h>
#include <sys/types.h>
declare
mode_t umask(mode_t mode);
args
mode: 權限
return
success: 以前的權限掩碼
##庫函數和系統調用的區別 ###庫函數調用 #include <stdio.h>
移植性好 C庫函數相同 屬於過程調用 開銷較小 C標準庫默認分配了3個文件流 `FILE*`類型 stdin: 標準輸入 stdout: 標準輸出 stderr: 標準錯誤輸出
###系統調用 #include <unistd.h>
移植性差 各個操做系統的系統調用不一樣 須要在用戶空間和內核上下文環境間切換 開銷較大 Linux系統默認分配了3個文件描述符值 0: 標準輸入 1: 標準輸出 2: 標準錯誤輸出
例子1 簡單cp命令的實現
#include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <errno.h> #define MAXLINE 80 void if_error(int status_code, char *err_msg) { if (status_code < 0) { perror(err_msg); exit(errno); } } int main(int argc, char **argv) { int fd_read, fd_write, n; char buf[MAXLINE]; fd_read = open("/etc/passwd", O_RDONLY); if_error(fd_read, "open_read"); fd_write = open("./test_passwd", O_WRONLY|O_CREAT, 0664); if_error(fd_write, "open_write"); while ((n = read(fd_read, buf, MAXLINE)) > 0) { write(fd_write, buf, n); write(STDOUT_FILENO, buf, n); } //unlink("./test_passwd"); return 0; }
例子2 獲取文件的屬性
#include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> void if_error(int status_code, char *err_msg) { if (status_code < 0) { perror(err_msg); exit(errno); } } void get_perm(char *filename) { struct stat buf; int ret = stat(filename, &buf); if_error(ret, "stat"); if (buf.st_mode & S_IRUSR) printf("owner can read %s\n", filename); if (buf.st_mode & S_IWUSR) printf("owner can write %s\n", filename); if (buf.st_mode & S_IRGRP) printf("group can read %s\n", filename); if (buf.st_mode & S_IWGRP) printf("group can write %s\n", filename); if (buf.st_mode & S_IROTH) printf("others can read %s\n", filename); if (buf.st_mode & S_IWOTH) printf("others can write %s\n", filename); printf("\n"); } int main(int argc, char **argv) { int i; char *filename[3] = {"/etc/passwd", "/tmp/"}; for (i = 0; i < 2; i++) get_perm(filename[i]); return 0; }
例子3 遞歸列出目錄下全部文件
#include <sys/types.h> #include <sys/stat.h> #include <dirent.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #define MAXLINE 80 void if_null(void *ptr, char *err_msg) { if (ptr == NULL) { perror(err_msg); exit(errno); } } void list_file(char *path) { DIR *dir; struct dirent *file; struct stat info; char buf[MAXLINE]; dir = opendir(path); if_null(dir, "opendir"); while((file = readdir(dir)) != NULL) { /* ignone . and .. */ if(!strcmp(file->d_name, ".") || !strcmp(file->d_name, "..")) continue; sprintf(buf ,"%s/%s", path, file->d_name); lstat(buf, &info); if (S_ISDIR(info.st_mode)) { list_file(buf); } else { printf("%s\n", file->d_name); } } closedir(dir); } int main(int argc, char **argv) { list_file("/boot"); return 0; }