系统文件操作函数
系統級文件操作
執行程序時會自動打開三個文件:標準輸入,標準輸出和標準錯誤輸出。在C標準庫中分別用FILE *stdin,stdout,stderr表示。這三個文件的描述符分別是0,1和2,保存在FILE結構體中,頭文件unistd.h定義了三個文件描述符。
#define STDIN_FILENO 0 #define STDOUT_FILENO 1 #define STDERR_FILENO 2- unlink
#include <unistd.h>;
int unlink(const char *pathname);unlink()刪除一個name從文件系統,假如那個name是文件的最后鏈接且沒有進程打開它,該文件將被刪除。
unlink()? deletes? a name from the filesystem.? If that name was the last link to a file and no processes have the file open the file is deleted and the space it was using is made available? for? reuse.
If? the? name? was? the last link to a file but any processes still have the file open the file will remain in existence until the last file descriptor referring to it is closed.
If the name referred to a symbolic link the link is removed.
If the name referred to a socket, fifo or device the name for it is removed but processes which have the object open may continue to use it.
- open&close
pathname確省為當前路徑下面。
flags:一個值或幾個值的組合。
O_RDONLY:以只讀的方式打開文件.
O_WRONLY:以只寫的方式打開文件.
O_RDWR:以讀寫的方式打開文件.
O_APPEND:以追加的方式打開文件.
O_CREAT:假如文件不存在,創建一個文件。文件存在,不截短文件,要截短文件需指定O_TRUNC。
O_EXCL:如果使用了 O_CREAT 而且文件已經存在,就會發生一個錯誤。此外,若O_CREAT與O_EXCL同時設置,并且將要打開的文件為符號連接,則將導致打開文件失敗。
O_NOBLOCK:以非阻塞的方式打開一個文件.
O_TRUNC:如果文件已經存在,則刪除文件的內容.
O_LARGEFILE:大文件(>2G),2^31~=2G(采用64位偏移)。若不指定,文件大小達到2G時,出錯退出。
前面三個標志只能使用任意的一個。如果使用了 O_CREATE 標志,那么我們要使用 open 的第二種形式。還要指定 mode 標志,用來表示文件的訪問權限.mode 可以是以下情況的組合.
S_IRUSR 用戶可以讀 S_IWUSR 用戶可以寫 S_IXUSR 用戶可以執行 S_IRWXU 用戶可以讀寫執行
S_IRGRP 組可以讀 S_IWGRP 組可以寫 S_IXGRP 組可以執行 S_IRWXG 組可以讀寫執行
S_IROTH 其他人可以讀 S_IWOTH 其他人可以寫 S_IXOTH 其他人可以執行 S_IRWXO 其他人可以讀寫執行
S_ISUID 設置用戶執行 ID S_ISGID 設置組的執行 ID (s)
我們也可以用數字(八進制0)來代表各個位的標志.Linux 總共用 5 個數字來表示文件的各種權限. 00000.第一位表示設置用戶 ID.第二位表示設置組 ID,第三位表示用戶自己的權限位,第四位表示組的權限,最后一位表示其他人的權限.
每個數字可以取 1(執行權限),2(寫權限),4(讀權限),0(什么也沒有)或者是這幾個值的和。
比如我們要創建一個用戶讀寫執行,組沒有權限,其他人讀執行的文件.設置用戶 ID 位那么 我們可以使用的模式是--1(設置用戶 ID)0(組沒有設置)7(1+2+4)0(沒有權限,使用缺省) 5(1+4)即 10705:
open("temp",O_CREAT,10705);
同時注意:文件的最終權限,需要與umask相與。
The letters rwxXst select file mode bits for the affected users: read (r), write? (w),? execute? (or search? for? directories) (x),
execute/search only if the file is a directory or already has execute permission for some user (X),
set user or group ID on execution (s),? restricted? deletion? flag? or sticky bit (t).
注:文件即使不關閉,程序執行完后,也會回收系統資源,稱為隱式回收系統資源。
- read&write
#include <unistd.h>;
ssize_t read(int fd, void *buffer,size_t count); ssize_t write(int fd, const void *buffer,size_t count);返回讀寫的字節數。
注:read讀普通文件,讀到文件尾時返回0。 write寫多個字節時,要么出錯,要么返回多個字節,不會返回0。兩函數都可能由于信號中斷而讀取到少量數據。
讀寫常規文件,read/write都不會阻塞;設備文件時才阻塞。
- 示例,復制文件
?
- fcntl
F_SETFL改寫文件打開方式。
F_GETFL獲取文件打開方式。
F_SETFL需第三參數,參數為文件打開標志,成功0,失敗-1。
F_GETFL不需要第三參數,成功:文件打開標志,失敗-1。
flags = fcntl(fd, F_GETFL); flags |= O_NONBLOCK; fcntl(fd, F_SETFL, flags);- lseek
設備文件是不可以設置偏移量的。如果不支持lseek,則lseek返回-1. 成功返回當前偏移量。 off_t =>int 從0計數偏移量。
whence:SEEK_SET, SEEK_CUR, SEEK_END
注:不可越界開頭,可越界文件未。 可用于求當前偏移量,文件長度。 偏移量允許超過文件末尾,這種情況下,對該文件的下一次寫操作將延長文件,中間空洞的地方讀出來都是0。
- truncate
擴展文件長度
#include <sys/types.h> int truncate(const char *path, off_t length); int ftruncate(int fd, off_t length);=>truncate a file to a specified length. 將文件改為指定長度,可清空文件(length = 0)。
- 注意
注:vi編譯器在文件尾加“\n",當文件有內容時。
open文件時,文件已緩沖到內存中,內核內存緩沖4K~8K(最小)。 庫函數有緩沖區。 庫函數讀寫時間<系統調用讀寫時間。
?
strings示例
打印文件中可打印字符,類似strings,超過拷貝區后有兩種實現方案:拷貝檢測到的打印字符復制到緩沖區;倒退文件當前偏移量。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <fcntl.h>#define BUF_SIZE 128 int main(int argc, char **argv) {if(argc < 3){ printf("Usage: %s filename num\n", argv[0]);exit(1);} int ret = 0;int fd = 0;char buf[BUF_SIZE] = {0};int num = 0;int i = 0, j = 0, cs_num = 0;int able_p = atoi(argv[2]); int flag = 0;off_t buf_of = 0, tmp_of = 0, off = 0;if(able_p <= 2){ able_p = 2;} ret = access(argv[1], F_OK);if(ret != 0){printf("%s doesn't exist or have permission.\n", argv[1]);exit(1);}fd = open(argv[1], O_RDONLY);if(fd < 0){perror("open");exit(1);}buf_of = 0;while((num = read(fd, buf + buf_of, sizeof(buf) - buf_of)) > 0){tmp_of = buf_of;buf_of = 0;for(i = tmp_of; i < num+tmp_of; i++){if( (buf[i]>= ' ') && (buf[i] <= '~')){if(flag == 1){putchar(buf[i]);continue;} else {cs_num++;}} else {if(flag == 1){putchar('\n');flag = 0;}cs_num = 0;}if(cs_num >= able_p){for(j = 1; j <= cs_num; j++){putchar(buf[i-cs_num + j]);}flag = 1;cs_num = 0;buf_of = 0;} else if(i == num - 1){ //#if 0off = lseek(fd, 0, SEEK_CUR);if(off == (off_t)-1){perror("lseek");exit(1);}off = lseek(fd, off-cs_num, SEEK_SET);if(off == (off_t)-1){perror("lseek");exit(1);}buf_of = 0;cs_num = 0; //#endif #if 0for(j = 1; j <= cs_num; j++){buf[j-1]=buf[i-cs_num+j];// printf("[[[0x%x]]]",(char)buf[j-1]); }buf_of = cs_num; #endif}}}close(fd);return 0; }?
轉載于:https://www.cnblogs.com/embedded-linux/p/5037378.html
總結
- 上一篇: sql server转oracle需要注
- 下一篇: oracle树形语句