linux高级编程——文件IO

 1.相关介绍及常用函数

Linux高级编程中的文件I/O(输入/输出)是操作系统编程中的一个重要部分。在Linux环境下,文件I/O操作通常涉及到对文件描述符(file descriptor)的管理和操作。以下是一些常见的文件I/O操作和相关的系统调用:

  1. 打开文件

    • 使用open()系统调用打开一个文件,并返回一个文件描述符。
    • 语法:int open(const char *pathname, int flags, mode_t mode);
  2. 关闭文件

    • 使用close()系统调用关闭一个文件描述符。
    • 语法:int close(int fd);
  3. 读取文件

    • 使用read()系统调用从文件中读取数据。
    • 语法:ssize_t read(int fd, void *buf, size_t count);
  4. 写入文件

    • 使用write()系统调用向文件写入数据。
    • 语法:ssize_t write(int fd, const void *buf, size_t count);
  5. 文件定位

    • 使用lseek()系统调用改变文件描述符的文件偏移量。
    • 语法:off_t lseek(int fd, off_t offset, int whence);
  6. 文件属性

    • 使用stat()fstat()系统调用来获取文件状态信息。
    • 语法:int stat(const char *pathname, struct stat *buf);
    • 语法:int fstat(int fd, struct stat *buf);
  7. 文件截断

    • 使用truncate()ftruncate()系统调用来截断文件。
    • 语法:int truncate(const char *path, off_t length);
    • 语法:int ftruncate(int fd, off_t length);
  8. 文件同步

    • 使用fsync()fdatasync()系统调用来同步文件数据。
    • 语法:int fsync(int fd);
    • 语法:int fdatasync(int fd);
  9. 文件锁定

    • 使用fcntl()系统调用来设置或获取文件描述符的属性,包括文件锁定。
    • 语法:int fcntl(int fd, int cmd, ... /* arg */ );
  10. 文件权限和所有权

    • 使用chmod()chown()系统调用来更改文件权限和所有权。
    • 语法:int chmod(const char *path, mode_t mode);
    • 语法:int chown(const char *path, uid_t owner, gid_t group);

1.1 open()函数: 

原型: int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
功能:打开一个文件并获得关于这个文件的文件描述符
参数:
    pathname:文件名
    flags:文件的属性
    O_RDONLY: 以只读的方式打开文件
    O_WRONLY: 以只写的方式打开文件
    O_CREAT:文件不存在会自动创建
    O_TRUNC: 文件内容清零
    O_APPEND:向文件追加写入
    mode:文件权限  0666 (加入O_CREAT选项后,需要0666)
返回值:
    成功返回一个新的文件描述符
    失败返回-1

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
    int fd = open("1.txt",O_WRONLY| O_CREAT|O_TRUNC,0666);    
    if(-1 == fd)
    {
        fprintf(stderr,"open error\n");
        return 1;
    }
    printf("fd is %d\n",fd);
    return 0;
}

 1.2 write()函数

函数原型:ssize_t write(int fd, const void *buf, size_t count);
功能: 向fd对应的文件中写入从buf开始的count个字节数据
参数: 
    fd: 文件描述符
    buf:写入数据的首地址 
    count:写入数据的大小
返回值:
    成功返回实际向文件中写入的字节个数
    失败返回-1
 

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[])
{
    int fd = open("1.txt",O_WRONLY| O_CREAT|O_TRUNC,0666);    
    if(-1 == fd)
    {
        fprintf(stderr,"open error\n");
        return 1;
    }
    printf("fd is %d\n",fd);
    char buf[512]="hello";
    int ret = write(fd,buf,strlen(buf));
    if(-1 == ret)
    {
        fprintf(stderr,"write error\n");
        return 1;
    }

    close(fd);
    return 0;
}

1.3 read()函数 

函数原型: ssize_t read(int fd, void *buf, size_t count);
功能: 从fd对应文件的中读取count个字节数据存入到buf中
参数: 
    fd: 文件描述符
    buf:存储数据的空间首地址
    count:存储数据的大小
返回值: 
    成功返回实际读取到的字节个数
    失败返回-1

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
    int fd = open("1.txt",O_RDONLY);    
    if(-1 == fd)
    {
        fprintf(stderr,"open error\n");
        return 1;
    }
    printf("fd is %d\n",fd);
    char buf[512]={0};
    while(1)
    {
        int ret = read(fd,buf,sizeof(buf));
        if(ret<=0)
        {
            break;
        }
        printf("%s\n",buf);
    }

    close(fd);
    return 0;
}

1.4 close()函数

函数原型:int close(int fd)
功能:关闭文件描述符对应的文件
参数:
    fd:文件描述符
返回值: 
    成功返回0
    失败返回-1

1.5 lseek()函数

lseek() 函数在 Linux 系统中用于改变文件描述符的文件偏移量,也就是文件的当前读写位置。这个函数非常有用,因为它允许程序在文件中任意位置进行读写操作,而不仅仅是从文件的开头开始。

函数原型:off_t lseek(int fd, off_t offset, int whence);

参数说明

  • fd:文件描述符,是一个非负整数,表示要操作的文件。
  • offset:偏移量,可以是正数、负数或零。这个值将根据 whence 参数的设置来解释。
  • whence:指定 offset 参数的解释方式,可以是以下宏之一:
    • SEEK_SET:文件开头。offset 是相对于文件开头的绝对位置。
    • SEEK_CUR:当前位置。offset 是相对于当前文件偏移量的相对位置。
    • SEEK_END:文件结尾。offset 是相对于文件结尾的相对位置(通常是负值)。

返回值

  • 成功时,lseek() 返回新的文件偏移量,即操作后的文件位置。
  • 失败时,返回 -1 并设置 errno 以指示错误。

错误

  • EBADFfd 不是一个有效的文件描述符。
  • EINVALwhence 参数的值无效。
  • ESPIPE:文件是管道或FIFO,不支持 lseek()

假设我们有一个文件,我们想要从文件的第10个字节开始读取数据: 

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

int main() {
    int fd = open("example.txt", O_RDONLY);
    if (fd == -1) {
        perror("open");
        return 1;
    }

    off_t offset = 10; // 从文件开头的第10个字节
    off_t new_pos = lseek(fd, offset, SEEK_SET);
    if (new_pos == -1) {
        perror("lseek");
        close(fd);
        return 1;
    }

    // 现在可以继续使用 read() 来读取数据
    // ...

    close(fd);
    return 0;
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值