您的位置:首页 > 运维架构 > Linux

Linux C编程学习笔记(3):read、write、lseek函数及文件读写和文件读写指针的移动操作

2017-06-10 04:55 579 查看

my_rwl.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

//自定义错误处理函数
void my_err(const char *err_string,int line)
{
fprintf(stderr,"line:%d ",line); //标准错误输出
perror(err_string);  //输出错误原因
exit(1);
}

//自定义读数据函数
int my_read(int fd)
{
int len;
int ret;
int i;
char read_buf[64];

//获取文件长度并保持文件读写指针在文件开始处
if(lseek(fd,0,SEEK_END)==-1)  //将文件读写指针移动到文件末尾,有错误返回-1
{
my_err("lseek",__LINE__);  //调用错误处理函数,定位错误
}
if((len=lseek(fd,0,SEEK_CUR))==-1)  //获取文件读写指针的当前位置
{
my_err("lseek",__LINE__);  //__LINE__为预编译器内置宏,表示行数
}
if(lseek(fd,0,SEEK_SET)==-1)  //将文件读写指针移动到文件开头
{
my_err("lseek",__LINE__);
}

printf("len:%d\n",len);  //打印文件长度

//读数据
if((ret=read(fd,read_buf,len))<0)  //调用read函数
{
my_err("read",__LINE__);
}

//打印数据
for(i=0;i<len;i++)
printf("%c",read_buf[i]);
printf("\n");

return ret;  //ret为实际读到字节数
}
int main()
{
int fd;
char write_buf[32]="Hello World!";

//在当前目录下创建文件example_2.c
//if((fd=creat("example_2.c",S_IRWXU))==-1)
if((fd=open("example_2.c",O_RDWR|O_CREAT|O_TRUNC,S_IRWXU))==-1)
{
my_err("open",__LINE__);
}
else
{
printf("create file success\n"); 
}

//写数据
if(write(fd,write_buf,strlen(write_buf))!=strlen(write_buf))
//返回值与写入字节数不相等,有错误发生
{
my_err("write",__LINE__);
}
my_read(fd);  //调用自定义读数据函数

//演示文件的间隔
printf("————————————————————————————————————————————\n");
if(lseek(fd,10,SEEK_END)==-1)  //文件偏移量被设置为文件长度12+10,即22
{
my_err("lseek",__LINE__);
}
if(write(fd,write_buf,strlen(write_buf))!=strlen(write_buf))
 //在文件第23个字节处开始再写12个字节
{
my_err("write",__LINE__);
}
my_read(fd);  //读了共34个字节长度

close(fd);
return 0;
}


首先在当前目录下创建了example_2.c。

因为open的参数为O_RDWR|O_CREAT|O_TRUNC表示以可读可写创建一个文件,如果该文件存在,则将原文件数据清0,即覆盖掉。

然后向新创建文件写入数据。

read函数测试文件长度,然后读出全部数据,并且打印出来。



程序执行完后查看文件内容:



如果write对EOF之后的位置写入了数据,EOF之前与EOF之后的数据之间将会存在一个间隔,由上图中的ASCII码知,间隔中的数据为0。

read函数

1.原型

  #include<unistd.h>
  ssize_t read(int fd, void *buf,size_t count);


2.功能

  从打开的设备或文件中读取数据。

3.参数
4000

  count是请求读取的字节数,从fd所指向的文件中读上来的数据保存在缓冲区buf中。同时文件读写指针也会随读到的字节移动。

  注意返回值类型是ssize_t,表示有符号的size_t,这样既可以返回正的字节数、0(表示到达文件末尾)、也可以返回负值-1(表示出错)。

write函数

1.原型

  #include <unistd.h>
  ssize_t write(int fd, const void *buf, size_t count);


2.功能

  向打开的设备或文件中写数据。

3.参数

  count是请求写入的字节数,把缓冲区buf中的数据写入到由fd所指向的文件中。同时文件读写指针也会随之移动。

lseek函数

1.原型

#include <unistd.h>
#include <sys/types.h>
off_t lseek(int filedes, off_t offset, int whence);


2.功能

  每一个已打开的文件都有一个读写位置,当打开文件时通常其读写位置是指向文件开头,若是以添加的方式打开文件(如O_APPEND),则读写位置会指向文件尾。当read()或write()时,读写位置会随之增加,lseek()便是用来控制该文件的读写位置。参数fildes 为已打开的文件描述符,参数offset 为根据参数whence来移动读写位置的位移数。

3.参数

  ① filders:已打开的文件描述符。

  ② offset:根据参数whence来移动读写位置的位移数。

  ③ whence:取值有以下三种

      SEEK_SET  参数offset 即为新的读写位置。

      SEEK_CUR  以目前的读写位置往后增加offset 个位移量。

      SEEK_END  将读写位置指向文件尾后再增加offset 个位移。

      注意:当whence 值为SEEK_CUR 或SEEK_END 时,,参数offet 允许负值的出现。

4.常见使用方式

  ① 将读写位置移到文件开头时

  lseek(int fildes, 0, SEEK_SET);


  ② 将读写位置移到文件尾时

  lseek(int fildes, 0, SEEK_END);


  ③ 想要获取目前文件位置时

  lseek(int fildes, 0, SEEK_CUR);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  函数 c语言 编程 linux