文件读写函数分为两大类:标准库函数和系统调用。
标准函数:
#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
C语言学习笔记系列(7)文件操作
最新推荐文章于 2023-03-18 12:46:07 发布