系统文件操作函数
系統(tǒng)級文件操作
執(zhí)行程序時(shí)會自動打開三個(gè)文件:標(biāo)準(zhǔn)輸入,標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤輸出。在C標(biāo)準(zhǔn)庫中分別用FILE *stdin,stdout,stderr表示。這三個(gè)文件的描述符分別是0,1和2,保存在FILE結(jié)構(gòu)體中,頭文件unistd.h定義了三個(gè)文件描述符。
#define STDIN_FILENO 0 #define STDOUT_FILENO 1 #define STDERR_FILENO 2- unlink
#include <unistd.h>;
int unlink(const char *pathname);unlink()刪除一個(gè)name從文件系統(tǒng),假如那個(gè)name是文件的最后鏈接且沒有進(jìn)程打開它,該文件將被刪除。
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確省為當(dāng)前路徑下面。
flags:一個(gè)值或幾個(gè)值的組合。
O_RDONLY:以只讀的方式打開文件.
O_WRONLY:以只寫的方式打開文件.
O_RDWR:以讀寫的方式打開文件.
O_APPEND:以追加的方式打開文件.
O_CREAT:假如文件不存在,創(chuàng)建一個(gè)文件。文件存在,不截短文件,要截短文件需指定O_TRUNC。
O_EXCL:如果使用了 O_CREAT 而且文件已經(jīng)存在,就會發(fā)生一個(gè)錯(cuò)誤。此外,若O_CREAT與O_EXCL同時(shí)設(shè)置,并且將要打開的文件為符號連接,則將導(dǎo)致打開文件失敗。
O_NOBLOCK:以非阻塞的方式打開一個(gè)文件.
O_TRUNC:如果文件已經(jīng)存在,則刪除文件的內(nèi)容.
O_LARGEFILE:大文件(>2G),2^31~=2G(采用64位偏移)。若不指定,文件大小達(dá)到2G時(shí),出錯(cuò)退出。
前面三個(gè)標(biāo)志只能使用任意的一個(gè)。如果使用了 O_CREATE 標(biāo)志,那么我們要使用 open 的第二種形式。還要指定 mode 標(biāo)志,用來表示文件的訪問權(quán)限.mode 可以是以下情況的組合.
S_IRUSR 用戶可以讀 S_IWUSR 用戶可以寫 S_IXUSR 用戶可以執(zhí)行 S_IRWXU 用戶可以讀寫執(zhí)行
S_IRGRP 組可以讀 S_IWGRP 組可以寫 S_IXGRP 組可以執(zhí)行 S_IRWXG 組可以讀寫執(zhí)行
S_IROTH 其他人可以讀 S_IWOTH 其他人可以寫 S_IXOTH 其他人可以執(zhí)行 S_IRWXO 其他人可以讀寫執(zhí)行
S_ISUID 設(shè)置用戶執(zhí)行 ID S_ISGID 設(shè)置組的執(zhí)行 ID (s)
我們也可以用數(shù)字(八進(jìn)制0)來代表各個(gè)位的標(biāo)志.Linux 總共用 5 個(gè)數(shù)字來表示文件的各種權(quán)限. 00000.第一位表示設(shè)置用戶 ID.第二位表示設(shè)置組 ID,第三位表示用戶自己的權(quán)限位,第四位表示組的權(quán)限,最后一位表示其他人的權(quán)限.
每個(gè)數(shù)字可以取 1(執(zhí)行權(quán)限),2(寫權(quán)限),4(讀權(quán)限),0(什么也沒有)或者是這幾個(gè)值的和。
比如我們要創(chuàng)建一個(gè)用戶讀寫執(zhí)行,組沒有權(quán)限,其他人讀執(zhí)行的文件.設(shè)置用戶 ID 位那么 我們可以使用的模式是--1(設(shè)置用戶 ID)0(組沒有設(shè)置)7(1+2+4)0(沒有權(quán)限,使用缺省) 5(1+4)即 10705:
open("temp",O_CREAT,10705);
同時(shí)注意:文件的最終權(quán)限,需要與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).
注:文件即使不關(guān)閉,程序執(zhí)行完后,也會回收系統(tǒng)資源,稱為隱式回收系統(tǒng)資源。
- 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);返回讀寫的字節(jié)數(shù)。
注:read讀普通文件,讀到文件尾時(shí)返回0。 write寫多個(gè)字節(jié)時(shí),要么出錯(cuò),要么返回多個(gè)字節(jié),不會返回0。兩函數(shù)都可能由于信號中斷而讀取到少量數(shù)據(jù)。
讀寫常規(guī)文件,read/write都不會阻塞;設(shè)備文件時(shí)才阻塞。
- 示例,復(fù)制文件
?
- fcntl
F_SETFL改寫文件打開方式。
F_GETFL獲取文件打開方式。
F_SETFL需第三參數(shù),參數(shù)為文件打開標(biāo)志,成功0,失敗-1。
F_GETFL不需要第三參數(shù),成功:文件打開標(biāo)志,失敗-1。
flags = fcntl(fd, F_GETFL); flags |= O_NONBLOCK; fcntl(fd, F_SETFL, flags);- lseek
設(shè)備文件是不可以設(shè)置偏移量的。如果不支持lseek,則lseek返回-1. 成功返回當(dāng)前偏移量。 off_t =>int 從0計(jì)數(shù)偏移量。
whence:SEEK_SET, SEEK_CUR, SEEK_END
注:不可越界開頭,可越界文件未。 可用于求當(dāng)前偏移量,文件長度。 偏移量允許超過文件末尾,這種情況下,對該文件的下一次寫操作將延長文件,中間空洞的地方讀出來都是0。
- truncate
擴(kuò)展文件長度
#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",當(dāng)文件有內(nèi)容時(shí)。
open文件時(shí),文件已緩沖到內(nèi)存中,內(nèi)核內(nèi)存緩沖4K~8K(最小)。 庫函數(shù)有緩沖區(qū)。 庫函數(shù)讀寫時(shí)間<系統(tǒng)調(diào)用讀寫時(shí)間。
?
strings示例
打印文件中可打印字符,類似strings,超過拷貝區(qū)后有兩種實(shí)現(xiàn)方案:拷貝檢測到的打印字符復(fù)制到緩沖區(qū);倒退文件當(dāng)前偏移量。
#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; }?
轉(zhuǎn)載于:https://www.cnblogs.com/embedded-linux/p/5037378.html
總結(jié)
- 上一篇: sql server转oracle需要注
- 下一篇: 信息安全系统设计基础第十五周总结