C语言学习笔记系列(7)文件操作

  文件读写函数分为两大类:标准库函数和系统调用。
标准函数:
#include <stdio.h>
FILE *fopen(const char *filename, const char *mode);
size_t fread(void *ptr, size_t size, size_t nitems, FILE*stream);
size_t fwrite(const void *ptr, size_t size, size_t nitems,FILE *stream);
int fclose(FILE *stream);
int fseek(FILE *stream, long offset, int whence);

 函数的使用方法比较容易理解,只是fopen/open的参数在取值上需要注意。关于fopen的参数mode的取值说明如下。默认打开文件是以文本方式打开,如果在mode中加入b,则是以二进制方式打开。
r/rb:只读方式打开文件
w/wb:若文件不存在,则创建新文件写入,如果文件存在,则先把旧文件清成0byte再写入。
a/ab:在文件末尾追加;打开或者创建新文件在文件尾写入。
r+/rb+/r+b:对文件进行读写(即使文件不存在也不会创建)。
w+/wb+/w+b:对文件进行读写(文件清0长度或者创建新文件)。
a+/ab+/a+b:对文件进行读写(打开或者创建新文件,写文件时在文件末尾追加,即使使用fseek也无效)。

 系统调用:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *path, int oflag, /* mode_t mode */...);

#include <unistd.h>
ssize_t read(int fildes, void *buf, size_t nbyte);
ssize_t write(int fildes, const void *buf, size_t nbyte);
int close(int fildes);
off_t lseek(int fildes, off_t offset, int whence);

 系统调用open的参数oflag和mode相对比较复杂,取值种类比较多。
O_RDONLY:只读
O_WRONLY:只写
O_RDWR:可读可写
 以上是必须三选一,以下是可选flag:
O_APPEND:写文件时在文件末尾追加。
O_CREAT:如果文件不存在,创建新文件,此时需要mode参数存在。
O_DSYNC: 使每次write等待物理I/O操作完成,但是如果写操作并不影响读取刚写入的数据,则不等待文件属性被更新。
O_EXCL:独占。如果与O_CREAT同时存在,文件存在时打开失败。
O_RSYNC:使每一个以文件描述符作为参数的read操作等待,直至任何对文件同一部分进行的未决写操作都完成。
O_SYNC:使每次write都等到物理I/O操作完成,包括由write操作引起的文件属性更新所需的I/O。
O_TRUNC:只对一般文件有效,如果文件打开正常,则把文件长度清为0.
oflag还可以取其他几种值,但是不常用,这里不再介绍。

 还有一系列函数,可以用来取得文件(包括普通文件,目录,管道,socket,字符,块等)的信息,因此可以用来判断文件是否存在。
  #include <sys/types.h>
  #include <sys/stat.h>
  int stat(const char *path, struct stat *buf);
  int lstat(const char *path, struct stat *buf);
  int fstat(int fildes, struct stat *buf);
stat:取得path指向文件的信息,如文件大小,创建时间等。
 lstat:与stat函数类似,不过如果指向的path是链接时,stat返回的是连接指向文件的信息,而lstat返回的则是连接本身的信息。
 fstat:取得句柄fildes所对应的文件的信息。(文件已经成功打开,不能使用该函数来判断文件是否存在。)
 返回的文件信息结构体详细信息如下:
struct stat {
  mode_t st_mode; /* File mode (see mknod(2)) */
  ino_t st_ino; /* Inode number */
  dev_t st_dev; /* ID of device containing a directory entry for this file */
  dev_t st_rdev; /* ID of device.This entry is defined only for char special or block special files */
  nlink_t st_nlink; /* Number of links */
  uid_t st_uid; /* User ID of the file's owner */
  gid_t st_gid; /* Group ID of the file's group */
  off_t st_size; /* File size in bytes */
  time_t st_atime; /* Time of last access */
  time_t st_mtime; /* Time of last data modification */
  time_t st_ctime; /* Time of last file status change */
  /* Times measured in seconds since */
  /* 00:00:00 UTC, Jan. 1, 1970 */
  long st_blksize; /* Preferred I/O block size */
  blkcnt_t st_blocks; /* Number of 512 byte blocks allocated*/ 
}
  函数正常返回为0,否则为-1.
  现在举例说明如下:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>

int main()
{
 FILE *fp = NULL;
 struct stat fsta;
 int ret = 0;
 char buf[32];
 char pbuf[32] = "abcdefg1234567";
 
 memset(&fsta, 0, sizeof(fsta));
 ret = stat("myfile", &fsta);
 if(ret == -1) {
  printf("ret:%d errno:%d/n",ret, errno);
  return(-1);
 } else {
  printf("file size:%d/n",fsta.st_size); 
 }
 if((fp = fopen("myfile", "rb+")) == NULL) {
  printf("file open error/n");
  return(-1);
 }
 fseek(fp, 0, SEEK_SET); //file's first location
 ret = fwrite(pbuf, 1, sizeof(pbuf), fp);
 printf("write size:%d/n", ret);
 printf("pbuf:%s/n", pbuf);
 
 memset(buf, 0, sizeof(buf));
 fseek(fp, 0, SEEK_SET); //file's first location
 ret = fread(buf, 1, sizeof(buf), fp);
 printf("read size:%d/n", ret);
 printf("buf:%s/n", buf);
 
 fclose(fp);
 
 memset(&fsta, 0, sizeof(fsta));
 ret = stat("myfile", &fsta);
 if(ret == -1) {
  printf("ret:%d errno:%d/n",ret, errno);
  return(-1);
 } else {
  printf("file size:%d/n",fsta.st_size); 
 }
 

  return 0;
}
当文件不存在时,运行结果为:
ret:-1 errno:2
创建一个大小为0的空文件后,运行结果为:
file size:0
write size:32
pbuf:abcdefg1234567
read size:32
buf:abcdefg1234567
file size:32

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值