Linux系统编程——基于文件描述符的文件操作(1)

概要:

  • 打开、创建和关闭文件
  • 读写文件
  • 文件定位
  • 获取文件信息

打开、创建和关闭文件

函数原型:
#include <sys/types.h> //头文件
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags); //文件名 打开方式
int open(const char *pathname, int flags, mode_t mode);//文件名 打开方式 权限

flags和mode都是一组掩码的合成值,flags表示打开或创建的方式,mode表示文件的访问权限。

flags 的选项:

  • O_CREAT参数:
#include <func.h>
int main(int argc,char* argv[])
{
	ARGS_CHECK(argc,2);
	int fd;
	fd=open(argv[1],O_RDONLY|O_CREAT);
	ERROR_CHECK(fd,-1,"open");
	printf("fd=%d
",fd);
	return 0;
}

open()函数出错时返回-1,创建成功时返回未使用的最小文件描述符

0 标准输入符

1 标准输出符

2 标准错误输出符

故该代码中open()返回值为3

  • O_CREAT加自定义权限:

当输入的文件名不存在时,自动创建文件,但该文件权限是有问题的,所以在open()函数后加上自定义权限参数

#include <func.h>

int main(int argc,char* argv[])
{
	ARGS_CHECK(argc,2);
	int fd;
	fd=open(argv[1],O_RDONLY|O_CREAT,0600);
	ERROR_CHECK(fd,-1,"open");
	printf("fd=%d
",fd);
	return 0;
}

若文件已存在则跳出,否则创建文件:

#include <func.h>

int main(int argc,char* argv[])
{
	ARGS_CHECK(argc,2);
	int fd;
	fd=open(argv[1],O_RDONLY|O_CREAT|O_EXCL,0600);
	ERROR_CHECK(fd,-1,"open");
	printf("fd=%d
",fd);
	return 0;
}

TRUNK参数:若文件已存在截断内容为0

#include <func.h>

int main(int argc,char* argv[])
{
	ARGS_CHECK(argc,2);
	int fd;
	fd=open(argv[1],O_RDONLY|O_TRUNC,0600);
	ERROR_CHECK(fd,-1,"open");
	printf("fd=%d
",fd);
	return 0;
}

close用于文件的关闭:

int close(int fd);//fd表示文件描述词,是先前由open或creat创建文件时的返回值。

文件使用完毕后,应该调用close关闭它,一旦调用close,则该进程对文件所加的锁全都被释放,并且使文件的打开引用计数减1,只有文件的打开引用计数变为0以后,文件才会被真正的关闭。


读写文件

函数原型:

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);//文件描述词 缓冲区 长度

ssize_t write(int fd, const void *buf, size_t count);

对于read和write函数,出错返回-1,读取完了之后,返回0, 其他情况返回读写的个数

read.c

#include <func.h>
int main(int argc, char* argv[])
{
    ARGS_CHECK(argc, 2);
    int fd;
    fd = open(argv[1], O_RDONLY);
    ERROR_CHECK(fd, -1, "open");
    printf("fd = %d
", fd);
    int ret;
    ret = read(fd, buf, sizeof(buf));
    ERROR_CHECK(ret, -1, "read");
    printf("buf = %s
", buf);
    return 0;
}

write.c

#include <func.h>

int main(int argc,char* argv[])
{
	ARGS_CHECK(argc,2);
	int fd;
	fd=open(argv[1],O_RDWR);
	ERROR_CHECK(fd,-1,"open");
	printf("fd = %d
",fd);
	int arr[5]={1,2,3,4,5};
	int ret;
	ret=write(fd,arr,sizeof(arr));
	ERROR_CHECK(fd,-1,"write");
	lseek(fd,0,SEEK_SET);   //从文件头开始计算
	memset(arr,0,sizeof(arr));
	ret=read(fd,arr,sizeof(arr));
	ERROR_CHECK(fd,-1,"read");
	printf("ret = %d,arr[0] = %d,arr[3] = %d
",ret,arr[0],arr[3]);
	return 0;
}


文件定位

函数lseek将文件指针设定到相对于whence,偏移值为offset的位置

#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);//fd文件描述词

whence 可以是下面三个常量的一个
SEEK_SET 从文件头开始计算
SEEK_CUR 从当前指针开始计算
SEEK_END 从文件尾开始计算

  • 文件空洞——通常用于多进程间通信的时候的共享内存
#include <func.h>
int main(int argc,char* argv[])
{
	ARGS_CHECK(argc,2);
	int fd;
	fd=open(argv[1],O_RDWR);
	ERROR_CHECK(fd,-1,"open");
	printf("fd=%d
",fd);
	int ret;
	ret=lseek(fd,1024,SEEK_SET);
	printf("lseek ret=%d
",ret);
	char c='H';
	write(fd,&c,sizeof(c));
	close(fd);
	return 0;
}

  • 改变文件大小
#include <func.h>

int main(int argc,char* argv[])
{
	ARGS_CHECK(argc,2);
	int fd;
	fd=open(argv[1],O_RDWR);
	ERROR_CHECK(fd,-1,"open");
	printf("fd=%d
",fd);
	int ret;
	ret=ftruncate(fd,1024);
	ERROR_CHECK(ret,-1,"ftruncate");
	close(fd);
	return 0;
}
获取文件信息

fstat和stat函数获取文件信息,调用完毕后,文件信息被填充到结构体struct stat变量中,函数原型为:

#include <sys/types.h>

#include <sys/stat.h>

#include <unistd.h>

int stat(const char *file_name, struct stat *buf); //文件名 stat结构体指针

int fstat(int fd, struct stat *buf); //文件描述词 stat结构体指针

stat结构体:

struct stat {
dev_t st_dev; /* 如果是设备,返回设备表述符,否则为0 */
ino_t st_ino; /* i节点号 */
mode_t st_mode; /* 文件类型  无符号短整型 */
nlink_t st_nlink; /* 链接数 */
uid_t st_uid; /* 属主ID */
gid_t st_gid; /* 组ID */
dev_t st_rdev; /* 设备类型 */
off_t st_size; /* 文件大小,字节表示 */
blksize_t st_blksize; /* 块大小 */
blkcnt_t st_blocks; /* 块数 */
time_t st_atime; /* 最后访问时间 */
time_t st_mtime; /* 最后修改时间 */
time_t st_ctime; /* 最后权限修改时间 */
};

EXAMPLE:获得文件的大小

  • 用stat实现
    #include<sys/stat.h> 
    #include<unistd.h> 
    int main() 
    {
        struct stat buf; 
        stat (“/etc/passwd”,&buf);
        printf(“/etc/passwd file size = %d 
”,buf.st_size);//st_size可以得到文件大小
    }
  • 用fstat实现
int fd = open (“/etc/passwd”,O_RDONLY); //先获得文件描述词 fstat(fd, &buf); 实例:
#include <func.h>
int main()
{
    int fd = open("/home/a.txt", O_RDONLY);
    if(fd == -1)
	{
        perror("open error");
        exit(-1);
     }
    struct stat buf;
    int iRet = fstat(fd, &buf);
    if(iRet == -1)
    {
    	perror("fstat error");
    	exit(-1);
    }
    printf("the size of file is : %d
", buf.st_size);
    return 0;
}
原文地址:https://www.cnblogs.com/Mered1th/p/10699085.html