文件IO与标准IO的复习

来源:互联网 发布:淘宝优惠券制作 编辑:程序博客网 时间:2024/06/06 04:40

一、标准IO

相关头文件:#include <stdio.h>

相关函数:fopen 、 fread、fwrite、fgetc、fputc、fgets、fputs、fseek。

相关数据类型: FILE*

错误处理:perror();

打开文件:

FILE * fp  = fopen("xxxx", "mode");

fopen中的mode 分为:r 只读,文件必须存在;

  r+可读可写,文件必须存在;

  w 只写,会重新建立文件,若存在,则擦除原来的文件长度;

 w+  可读可写,同上;

a  追加只写,文件不存在则创建,存在则再文件尾追加数据,

a+ 追加可读可写,同上。

        系统默认3个数据流:stdin(0), stdout(1), stderr(2);

fclose(fp); //关闭流

简单实例:

FILE * fp;if( (fp = fopen( "1.txt", "r")) == NULL ){perror("fail to fopen");return -1;}fclose(fp);return 0;

fgetc()与fputc();

fgetc(FILE* stream): 参数只要一个FILE指针。作用,从FILE中读取一个字符,FILE文件指针向下一个字符移动。

fputc(int c, FILE*stream):c:为要写入的数值。作用,向FILE中写入一个字符,FILE文件指针向下一个字符移动。

简单实例:从键盘中读取一串字符,写入到stdout缓存中只写入数字。fflush用来刷新缓存。

int c;while(1){c = fgetc(stdin);if(( c >= '0') && ( c <= '9')) fputc( c, stdout);if( c == '\n') break;}fflush(stdout);putchar(10);//换行return 0;

fgets(char *s, int size, FILE* file),从FILE中读取size大小的数据给s。遇到\0或\n结束,会在最后添加一个\0作为结束
fputs(char *s, FILE *file ),将s写入到file中,\0会被丢弃。
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); 从stream中读取nmemb个项的数据,而每个nmemb的大小为size,放入ptr中。
size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);  将ptr中的数据写入到stream中。
简单实例:mycopy  ,将一个文件拷贝至另一个文件中。


#include<stdio.h>#include<string.h>#include<errno.h>#define N 64int main(int argc, char * argv[]){int n;char buf[N];FILE * fps, * fpd;if(argc < 3){printf("Usage: %s <src_file> <dst_file> \n", argv[0] );return -1;}if(( fps = fopen(argv[1], "r")) == NULL){fprintf(stderr,"fail to fopen %s:%s \n",argv[1],strerror(errno));return -1;}if(( fpd = fopen(argv[2], "w")) == NULL){fprintf(stderr,"fail to fopen %s:%s \n",argv[2],strerror(errno));return -1;}while(( n = fread(buf, 1, N, fps)) > 0){printf("%s \n",buf);fwrite(buf, 1, N, fpd);}fclose(fps);fclose(fpd);return 0;}

对于系统来说,频繁的调用底层标准IO,每次都会进行系统调用,会比较耗系统的资源。所以引进了标准文件IO。
二、文件IO
相关头文件:#include <unistd.h>
 #include <sys/types.h>
  #include <sys/stat.h>
   #include <fcntl.h>
相关函数:open 、 read、write。
相关数据类型: int fd。//文件描述符。从0 向上增长。
错误处理:perror();
详细分析: 
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
pathname为文件路径.
flags为标识符 常用标识符如下:
O_RDONLY  :只读打开文件
O_WRONLY :只写打开文件
O_RDWR   :   读写打开文件
O_CREAT  :文件不存在则创建,mode用来指定文件rwx
O_EXCL     :文件存在则返回错误
O_TRUNC  :文件存在则删除原有数据
O_APPEND :追加打开文件。读写位置只想文件末尾。
mode为文件模式
#include<stdio.h>#include<unistd.h>#include<sys/stat.h>#include<fcntl.h>int main(){int fd;if( (fd = open("./test.txt",O_RDWR|O_CREAT|O_TRUNC, 0777)) < 0 ){perror("fail to open");return -1;}close(fd);return 0;}



 ssize_t read(int fd, void *buf, size_t count); 从fd 中读取数据,存入到buf中,读入数据大小为count,返回值为:实际上读取文件的大小。失败返回-1或错误码。
 ssize_t write(int fd, const void *buf, size_t count); 将buf中的数据写入到fd中,数据大小为count,返回值为:实际上写入文件的大小。失败返回-1或错误码。
 off_t lseek(int fd, off_t offset, int whence);offset为偏移值,whence为从哪偏移,可选宏为:SEEK_SET 文件起始位置,SEEK_CUR 文件当前位置,SEEK_END文件结束位置。
简单实例:将文件1中的最后10K数据写入到文件2 中。
#include<unistd.h>#include<sys/stat.h>#include<fcntl.h>#include<stdlib.h>#include<stdio.h>#define BUFFER_SIZE 1024#define SRC_FILE_NAME "./usb.c"#define DEST_FILE_NAME "./test.txt"#define OFFSET 10240int main(){int fds, fdd;unsigned char buff[BUFFER_SIZE];int read_len;if((fds = open(SRC_FILE_NAME,O_RDONLY)) < 0){perror("fail to open fds");}if((fdd = open(DEST_FILE_NAME,O_WRONLY|O_CREAT)) < 0){perror("fail to open fdd");}lseek(fds, -OFFSET, SEEK_END);while((read_len = read(fds, buff, sizeof(buff))) > 0){write(fdd, buff, read_len);}close(fds);close(fdd);return 0;}

文件锁
      struct flock {
               ...
               short l_type;    /* Type of lock: F_RDLCK, 读锁
                                         F_WRLCK 写锁, F_UNLCK 没有锁*/


               short l_whence;  /* How to interpret l_start:
                                   SEEK_SET, SEEK_CUR, SEEK_END */
               off_t l_start;   /* Starting offset for lock */
               off_t l_len;     /* Number of bytes to lock */
/./以上三个确定 锁的起始位置,加锁区域的长度。
               pid_t l_pid;     /* PID of process blocking our lock   进程号
                                   (F_GETLK only) */
               ...
           };
相关函数:fcntl:      
 头文件:#include <unistd.h>
               #include <fcntl.h>
  int fcntl(int fd, int cmd, ... /* arg */ );
cmd包括:F_GETLK::检测文件锁状态
 F_SETLK:设置lock的文件锁
 F_SETLKW::可wait 阻塞的设置。

简单实例   lock_set.cint lock_set(int fd, int type){struct flock old_lock, lock;//初始化锁lock.l_whence = SEEK_SET; //从文件头开始就上锁lock.l_start = 0;lock.l_len = 0;lock.l_pid = -1;    lock.l_type = type;fcntl(fd, F_GETLK, &lock);   //得到锁的状态,赋值给lock中的l_typeif( lock.l_type != F_UNLCK)  //是否上锁,上锁则进入判断{if(lock.l_type == F_RDLCK)  //是不是读锁{printf("Read lock already set by %d\n", lock.l_pid);}else if(lock.l_type == F_WRLCK)//是不是写锁{printf("Write lock already set by %d\n",lock.l_pid);}}lock.l_type = type;  if( (fcntl(fd, F_SETLKW, &lock)) < 0 ) //等待上锁{printf("Lock failed:type = %d \n", lock.l_type);return -1;}switch(lock.l_type)   {case F_RDLCK:printf("Read lock set by %d\n", getpid());break;case F_WRLCK:printf("Write lock set by %d\n",getpid());break;case F_UNLCK:printf("Release lock by %d\n",getpid());return 1;break;}return 0;}



原创粉丝点击