Unix 环境高级编程第3版 编程习题

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;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值