(只写了文件调用的,C库自己看吧)
1、系统调用
定义:指操作系统提供给用户程序的调用的一组“特殊接口”,用户程序可以通过这组特殊接口来获得操作系统内核提供的服务
2、Linux文件描述符
当某个程序打开程序时,操作系统会返回相应的文件描述符,(相当于文件的别名,打开之后就只用这个fd来表示这个文件,和C库函数文件指针fd一样),这个描述符是一个正整数,012都被默认打开的三个文件使用了(标准输入、标准输出、标准出错处理)
3、带不带缓冲的I/O操作
1、不带I/O缓冲操作(系统调用),主要用到6个函数,ctreat、open、read、write、lseek、close,这里指的不带缓冲是指每个函数都只调用系统中的一个函数,这些函数虽然不是ANSI C的组成部分,但确是POSIX的组成部分。
2、带缓冲I/O操作(标准IO提供)。标准I/O库提供缓冲的目的的是尽可能减少调用read函数和write函数的次数,它也对每个I/O流自动的进行缓冲管理,从而避免应用程序需要考虑这一点带来的麻烦。
全缓冲:只有等填满IO缓冲区后在进行实际IO操作,对于驻留在磁盘上的文件,通常都是标准IO库实施全缓冲的。
行缓冲:当在输出输入中遇到换行符是,标准IO库执行IO操作,允许我们一次输出一个字符,但只有在写了一行之后才进行实际IO操作,当流涉及一个终端时,通常使用缓冲。
不带缓冲:标准IO库 不对字符进行缓冲存储,标准出错流stderr通常是不带缓冲的,使出错信息可以尽快显示出来,不管他们是有含有一个换行符。
4、int creat(const char *filename, mode_t mode )
1、包涵头文件
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>
2、filename :创建的文件名 (包含路径,缺省为当前路径) mode:创建模式 mode(相当于权限,其实改变的也只有用户自己的权限,别人的权限他也改不了)S_IRUSR 可读 S_IWUSR可写 S_IXUSR 可执行 S_IXRWU可读可写可执行,可以选这些宏也可以 用数字表示
3、返回文件描述词,有错误会返回-1,错误代码存入errno(系统全局变量)中
5、int open(const char *pathname, int flags)//打开或者是要创建的名字,mode创造新文件的权限参数
int open(const char *pathname, int flags,mode_t mode);
flags:打开方式常用方式如下
O_RDONLY O_WRONLY O_RDWR :只读只写读写
O_CREAT:要打开的文件不存在就自动创建该文件
O_EXCL:检查文件是否存在,不存在就创建,否则打开文件错误
O_TRUNC:若文件存在以写的方式打开,会使文件长度清零
O_NONBLOCK:以不可阻断的方式打开文件,也就是无论有无数据读取或等待,都会立即返回进程之中。
close(int fd):对应关闭文件。
6、int read(int fd, const void *buf, size_t length)
int write(int fd, const void * buf, size_t length)
1、包含头文件:#include<unistd.h>
2、读从文件描述符fd所指定的文件中读取length个字节到buf所指向的缓冲区中,返回值为实际读取的字节数。写把length个字节从buf指向的缓冲区中写到文件描述符fd所指向的文件中,返回值为实际写入的字节数。
不保证读写的是指定字节数,所有应该有错误判断
#include <stdio.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> //#include <error.h> int main(int argc,char *argv[]) { int fd; int i; char buffer[] = "hello"; char *ptr = NULL; int bytes_write; int bytes = 5; if(argc != 2) { printf("please input the flie name :"); exit(0); } if((fd = open(argv[1],O_WRONLY | O_CREAT| O_TRUNC,0644)) == -1) { perror("open file error"); exit(-1); } for( i = 0;i < 3;i++) { ptr = buffer; while(bytes_write = write(fd,ptr,bytes)) { if(-1 == bytes_write) { perror("write error"); } else if(bytes_write == bytes) { break; } else { bytes -= bytes_write; ptr += bytes_write; } } if(-1 == bytes_write) { break; } write(fd,"\n",1); } close(fd); return 0; }
7、int lseek(int fd, offset_t offset, int whence)
将文件读写指针相对whence移动offset个字节。操作成功时,返回文件指针相对于文件头的位置。文件里都有类似于文件指针读写的东西,读取时移动,当写入结束想读取的时候,这时候(文件指针读写)在文件末尾,所以读不到数,需要重置(文件指针读写)。
whence 可使用的值:SEEK_SET相对文件开头,SEEK_CUR相对文件读写指针的当前位置,SEEK_END相对于文件末尾。offset可取负值,表示向前移动
8、使用lseek计算文件长度
由于lseek函数的返回值为文件指针相对于文件头的位置,因此下面调用的返回值就是文件的长度: lseek(fd, 0, SEEK_END),用这个也可以判断文件内容是否写完。
9、hello回车符三行
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define MAX 100 int read_line(int fd, char *buf, int count) { int i; char ch; for(i = 0; i < count; i++) { if((read(fd,&ch,1)) < 0) { perror("read error!\n"); exit(1); } if(ch == '\n') { buf[i] = '\0'; return i; } buf[i] = ch; } buf[i - 1] = '\0'; return count; } int main() { int i; int fd; int w_count; int r_count; char filename[MAX]; char r_buf[MAX]; char w_buf[MAX]; printf("Please input filename:\n"); scanf("%s",filename); if((fd = open(filename, O_CREAT | O_RDWR, 0755)) < 0) { perror("open error!\n"); exit(1); } for(i = 0; i < 3; i++) { memset(w_buf,0,sizeof(w_buf)); scanf("%s",w_buf); if((w_count = write(fd,w_buf,strlen(w_buf))) < 0) { perror("write error!\n"); exit(1); } else { write(fd,"\n",1); } } lseek(fd,0,SEEK_SET); #if 0 if((r_count = read(fd,r_buf,sizeof(r_buf))) < 0) { perror("read error!\n"); exit(1); } else { r_buf[w_count * 3 + 3] = '\0'; printf("read data: %s\n",r_buf); } #endif for(i = 0; i < 3; i++) { memset(r_buf,0,sizeof(r_buf)); read_line(fd,r_buf,100); printf("read data: %s\n",r_buf); } close(fd); return 0; }
标签:文件,int,C语言,write,fd,操作,include,buf From: https://www.cnblogs.com/gunancheng/p/17500271.html