一 、 文件操作的系统函数
1.open(),使用man 2 open查询帮助文档。
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
有两个函数模型,需要参数是打开文件的路径,打开的方式(O_RDONLY,OWRONLY,O_RDWR以及其他可选),文件权限
返回值,如果打开成功会返回文件的描述符,失败会返回-1,并且设置errno.
int fd = open("/home/xxx/hello.c",O_RDWR);//使用读写方式打开一个/home/xxx/hello.c的文件,如果存在就会返回文件的描述符。
if(-1 == fd) //判断是否打开成功
{
perror("open");
return -1;
}
打开方式:
必须包含一下三种:O_RDONLY,OWRONLY,O_RDWR
可选择的方式:O_CREAT创建,O_APPEND追加,O_TRUNC清空
区别FILE *file和文件描述符int fd
前者是c语言中的打开文件fopen返回值,指向一个结构体,这个结构体中含有文件描述符。
后者是使用linux的系统函数打开文件。
2.close();关闭一个文件描述符。成功返回0,失败返回-1并设置errno;头文件在<unistd.h>
3.creat();创建一个文件。
int creat(const char *pathname, mode_t mode);
其中第一个参数是路径,第二个参数是权限
权限采用八进制表示,分别表示rwx rwx rwx;0777表示可读可写。
成功创建返回文件描述符,否则返回-1并设置错误标志。
4.read();读操作
ssize_t read(int fd, void *buf, size_t count);
其中,第一个参数是要读的文件描述符(打开方式要包含RD),第二个参数是读到这个buf指针指向的空间,第三个参数表示读出的个数。
返回值表示实际读取的小,如果返回-1表示出错
5.write();写操作
ssize_t write(int fd, const void *buf, size_t count);
与read相似。
其中文件描述符也可以是标准输入输出的描述符STDIN_FILENO,STDOUT_FILENO
注意:STDIN_FILENO的作用及与stdin 的区别
1.stdin是FILE * 类型,STDIN_FILENO是int类型。
2.stdin的主要函数有:fread,fwrite,fclose
3.STDIN_FILENO,是初级I/O函数使用的,stdin是高级I/O函数调用的。
6.lseek();设置文件的指针,
off_t lseek(int fd, off_t offset, int whence);
第一个参数是文件描述符,
第二个是偏移量,
第三个是参照点,SEEK_SET,SEEK_CUR,SEEK_END.
其中SEEK_CUR和SEEK_END的偏移量可以是负数
文件操作的例子
1.普通文件的读写。cat命令
2.仿写cp命令
3.读取键盘上输入的一行数据(带有空格)。
#include <unistd.h> #include <stdio.h> #include <string.h> #include <stdlib.h> /**************************************************/ //代码比较混乱,主要有从标准输入读取一行数据(可以待有空格),字符串的切割 /**************************************************/ void split2(char *s,char d,char *r[5]); void split(char * s,char *d,char *r[5]); //两个字符串分割的函数, int main() { //使用read从标准输入中读取一行数据。 /* char ca[128] = {"/0"}; memset(ca,0,128); int flag = read(STDIN_FILENO,ca,128); if(flag == -1) { perror("readFromSTDIN"); return -1; } printf("%s ",ca); printf("字符串的大小是:%d ",strlen(ca)); strtok(ca," "); printf("%s ",ca); printf("字符串的大小是:%d ",strlen(ca)); return 0; */ //strtok使用分割字符串 /* char ca[128]= "hello nihao wecome hi"; int len =strlen(ca); printf("%d ",len); printf("%d ",sizeof(ca)); //使用strtok分解字符串 char *arr[5]={NULL}; char *p = strtok(ca," "); printf("%s ",p); printf("%s ",ca); //ca == p ===> hello //下面不需要制定切割的字符串,直接可以从NULL中对剩下的字符串进行切割 arr[0] = p; int i =1; while(1) { p = strtok(NULL," "); if(p == NULL || i > 4) { break; } arr[i] = p; i++; printf("%s ",p); } printf("finsh "); for(i=0 ;i<5;i++) { if(arr[i] == NULL ) { break; } printf("%s ",arr[i]); } //使用strtok会破坏原来的数据。 len =strlen(ca); printf("%d ",len); printf("%d ",sizeof(ca)); //但是可以使用这个命令来去除字符串结尾的。 */ char ca[256]; readFromSTDIN(ca,256); printf("%s ",ca); char *result[5] = {NULL}; //split(ca," ",result); split2(ca,' ',result); int i =0; for(;i<5;i++) { if(result[i] == NULL) { //printf("*"); break; } printf("%s ",result[i]); } } //从标准读中获取一行数字 int readFromSTDIN(char * p,int count) { //memset(p,0,count); int flag = read(STDIN_FILENO,p,count); if(flag == -1) { perror("readFromSTDIN"); return -1; } strtok(p," "); //p = strchr(p,' '); //*p = ' '; //一个函数去除 并且设置' '; return 1; } //分割字符串 void split(char * s,char *d,char *r[5]) { char *p = strtok(s,d); r[0] = p; int i =1; while(1) { p = strtok(NULL,d); if(p == NULL || i > 4) { break; } r[i] = p; i++; } } void split2(char *s,char d,char *r[5]) { char * pre =s; char * cur =s; int i = 0; while(1) { cur = strchr(cur,d); if(cur == NULL || i > 3) { r[i] = pre; return; } char *tmp = (char *)malloc(64); //char *tmp =NULL; strncpy(tmp,pre,cur-pre); r[i] = tmp; i++; //printf("%s ",r[i]); cur = cur + 1; pre = cur; } }