3.6 使用追加标志打开一个文件以便读写,能否仍用lseek在任一位置开始读?能否用lseek更新文件中任一部分的数据?编写一段程序验证
用到的函数原型:
1)open函数:用以打开文件,产生文件描述符(对应的文件句柄),函数返回值为fd
int open(const char * path, int flags);
int open(const char * path, int flags, mode_t mode);
const char* path 代表要打开或者创建的文件名字,可以用绝对路径或者相对路径
flags 说明函数的打开选项,例如:O_RDONLY 以只读方式打开文件、O_WRONLY 以只写方式打开文件、O_RDWR 以可读写方式打开文件、O_CREAT 若欲打开的文件不存在则自动建立该文件等
2)read 函数:用以从打开的文件中读取数据
ssize_t read(int fd, void *buf, size_t nbytes);
fd : 文件描述符,也是open函数的返回值
void * buf :读入的缓冲区
size_t nbytes : 读入的字节数
3)lseek 函数 : 为打开文件设置一个偏移量
off_t lseek(int fd, off_t offset, int whence);
fd:文件描述符
offset:为打开文件设置偏移量
whence:offset的偏移方式 SEEK_SET:文件开始处,SEEK_CUR:文件当前位置,SEEK_END:文件末尾
4)write 函数:向打开文件写入内容
ssize_t write(int fd, void *buf, size_t nbytes);
fd:文件描述符
buf:待写入文件的内容
nbytes:待写入的长度 若是char*s,长度为strlen(s) 而非 sizeof(s)
习题结论:可以用lseek设置偏移量在文件的指定位置开始读,写入文件时数据只能从文件末尾写
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char buf[80];
int fd;
const char* path = "test.txt";
fd = open(path,O_RDWR); // 这里的path为相对路径,可以用lseek在任一位置读
off_t offsize = lseek(fd,1,SEEK_SET); // 偏移1位
ssize_t size = read(fd,buf,sizeof(buf));
printf("文件描述符为 %d\n",fd);
printf("偏移量 %ld \n",offsize);
printf("读取的字节数目 %ld \n",size);
printf("读取的字节为%s",buf);
char* s = "I want to write something";
ssize_t size_w = write(fd,s,strlen(s));
printf("往文件中写的长度为%ld\n",size_w);
}
4.6 编写一个类似cp(l)的程序,复制包含空洞的文件,但不将字节0写到输入文件中去
复制文件:cp a b ;a 为源文件,b为新复制的文件,要求状态、权限、内容均相同。
int lstat(const char * restrict pathname,struct stat * restrict buf) ;
lstat用于获取文件状态,buf 指针指向stat结构,stat用来访问文件的属性。定义 : struct stat buf,文件大小 : buf.st_size
#include<fcntl.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<stdio.h>
#include<stdlib.h>
#define max 655
int main(int argc,char* argv[])
{
struct stat buf;
int fd,fd2;
char buff[max];
if(lstat(argv[1],&buf)<0)
{
printf("lstat error");
}
else{
long size = buf.st_size; // 文件的长度
// printf("%ld",size);
if((fd = open(argv[1],O_RDWR))==-1)
{
printf("open read failed");
}
if((fd2 = open(argv[2],O_RDWR))==-1)
{
printf("open writefile failed\n");
// 无法打开预复制的文件,则去创一个新文件
// creat参数2 mode 与 buf一致
if((fd2 = creat(argv[2],buf.st_mode))==-1)
{
printf("creat file failed");
}
}
if(read(fd,buff,size)==-1)
{
printf("read error");
}
if(write(fd2,buff,size)==-1)
{
printf("write error");
}
close(fd); //关描述符fd
close(fd2); // 关描述符fd2
}
return 0;
}