文件操作相关函数(POSIX 标准 open,read,write,lseek,close)

时间:2022-12-14 19:07:49

POSIX标准

open函数属于Linux中系统IO,用于“打开”文件,代码打开一个文件意味着获得了这个文件的访问句柄。

int fd = open(参数1,参数2,参数3);

int fd = open(const char *pathname,int flags,mode_t mode);

1.句柄(file descriptor 简称fd)

   首先每个文件都属于自己的句柄,例如标准输入是0,标准输出是1,标准出错是2。

   每打开一个文件就会返回句柄来操作这个文件,一般是从3开始,然后4,5,6一直下去。

   close(fd)之后句柄就返回给系统,例如打开一个文件后fd是3,close之后再打开另外一个文件也还是3,但代表的文件不一样了。

2.使用open前需要先包含头文件

  #include <sys/types.h>

  #inlcude <sys/stat.h>

  #inlcude <fcntl.h>

3.参数1(pathname)

  即将要打开的文件路径,例如:“a.txt”当前目录下的a.txt文件

4.参数2(flags)

  flags分为两类:主类,副类

  主类:O_RDONLY 以只读方式打开   /   O_WRONLY 以只写方式打开   /O_RDWR 以可读可写方式打开

  三这是互斥的

  副类:

  O_CREAT 如果文件不存在则创建该文件

  O_EXCL 如果使用O_CREAT选项且文件存在,则返回错误消息

  O_NOCTTY 如果文件为终端,那么终端不可以调用open系统调用的那个进程的控制终端

  O_TRUNC 如果文件已经存在则删除文件中原有数据

  O_APPEND 以追加的方式打开主副可以配合使用,

  例如:O_RDWR|O_CREAT|O_TRUNC

5.参数3(mode)

  mode:如果文件被新建,指定其权限未mode

  mode是八进制权限码,0777表示文件所有者   该文件用户组     其他用户都有可读可写可执行权限

//例:
int fd;
fd = open("file",O_RDONLY);            
if(fd < 0)
    打开失败
else
    打开成功

  

read函数 读取文件  磁盘上一份 内存中一份

ssize_t count = read(参数1,参数2,参数3)

ssize_t read(int filedes,void *buf,size_t nbytes);

1.count 返回读到的字节数

若成功返回读到的字节数,若读到文件末尾返回0,若失败返回-1。

2.使用read前需要先包含头文件

#include <unistd.h>

3.参数1 (filedes)

filedes:open函数的成功返回值

4.参数2 (buf)

内存地址(开辟空间 栈、堆)

5.参数3 (nbytes)

数据大小(空间大小)

例如:
  1 #include <stdio.h>
  2 #include <fcntl.h>
  3 
  4 int main(int argc,char **argv)
  5 {
  6     int fd;
  7     char ch;
  8     //打开文件
  9     fd = open("file",O_RDONLY);//abcdefg
 10     if(fd < 0)
 11         //打开失败
 12         return -1;
 13     //读取文件
 14     read(fd,&ch,1);
 15     printf("%c\n",ch);
 16     read(fd,&ch,1);
 17     printf("%c\n",ch);
 18     return 0;
 19 }

  问题:那么一次到底读取多少字节合适?

  4096 8192
  BUFSIZ  8192
  char buf[BUFSIZ];
  read(fd,buf,sizeof(buf)-1);
 
write函数  将内存中的数据写入到文件中
ssize_t count = write(参数1,参数2,参数3)
ssize_t write(int filed,const void *buf,size_t nbytes);
1.count 写入的字节数
返回值:返回实际写入的字节数,若出错则返回-1。

2.使用write前需要先包含头文件

#include <unistd.h>

3.参数1(filed)
open函数的成功返回值
4.参数2(buf)
内存地址
5.参数3(nbytes)
数据大小
 
lseek函数  修改偏移量  影响下一次读写的操作
off_t currpos = lseek(参数1,参数2,参数3)
off_t lseek(int fileds,off_t offset,int whence);
1.currpos 新的文件偏移量
返回值:若成功返回新的文件偏移量,若出错返回-1。

2.使用write前需要先包含头文件

#include <unistd.h>

3.参数1(fileds)
open函数的成功返回值
4.参数2(offset)
偏移量     -?  0   +?
5.参数(whence)
相对位置
            文件开始            当前位置            文件末尾
            SEEK_SET           SEEK_CUR          SEEK_END
 
close函数关闭文件
close(参数1)
参数1:open函数的成功返回值
 
最后来一个程序来训练一下这几个函数(read和write函数复制一个文件)
#include<stdio.h>

#include<string.h>

#include<stdlib.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<unistd.h>

#include<fcntl.h>

 

#define BUFFER_SIZE 1024

 

int main( int argc,char **argv)

{

    int from_fd,to_fd;

    long file_len=0;

    int ret=1;

    char buffer[BUFFER_SIZE];

    char *ptr;

 

    //判断入参

    if(argc!=3)

    {

        printf("Usage:%s fromfile tofile !\n",argv[0]);

        exit(1);

    }

    

    //打开源文件

    if( (from_fd = open(argv[1],O_RDONLY | O_CREAT ))==-1)

    {

        printf("Open %s Error!\n",argv[1]);

        exit(1);

    }

 

    //创建目的文件

    if( (to_fd = open(argv[2], O_WRONLY | O_CREAT))==-1) 

    {

        printf("Open %s error! \n",argv[2]);

        exit(1);

    }

 

    //测得文件大小

    file_len=lseek(from_fd,0,SEEK_END);

    lseek(from_fd,0,SEEK_SET);

    printf("from file size is %d!\n",file_len);

 

    //进行文件拷贝

    while(ret)

    {

        ret = read(from_fd, buffer, BUFFER_SIZE);

        if(ret == -1)

        {

            printf("read error!\n");

            exit(1);

        }

        write(to_fd, buffer, ret );

        file_len = ret;

        bzero( buffer, BUFFER_SIZE );

    }

 

    printf("there are %d buyes data left without copy!\n",file_len);

    close(from_fd);

    close(to_fd);

 

    exit(0);

 

 

 

 

}