Linux系统编程-文件IO

文件IO

标准库IO函数和linux系统调用IO函数的区别:

  1. 标准C库的文件IO函数是跨平台的,在不同的平台上调用不同的系统API

  2. 标准C库的IO函数有缓冲区,而linux系统调用的没有缓冲区

    因此,在网络通信时尽量使用系统调用提高效率,而在读写磁盘时尽量使用库函数减少读写次数

标准库函数和系统调用的关系是 调用与被调用 的关系

文件描述符

在PCB中有一个文件描述符表,记录这个进程打开的所有文件信息。一般默认大小是1024,有3个默认打开的文件:标准输入,标准输出,标准错误默认都是打开的状态,文件描述符分别是0,1,2。这三个文件都指向当前终端 /dev/tty

每次新打开一个文件都会分配一个最小的可分配的文件描述符。

对于同一个进程,可以对同一个文件打开多次,每次分配的文件描述符是不一样的

常用函数

1. 对文件的操作函数

  1. open() 打开一个存在的文件 或者 创建一个新文件

  2. close() 关闭一个打开的文件,文件描述符被释放掉

    /*
    	int open(const char *pathname, int flags);
        int open(const char *pathname, int flags, mode_t mode);
        参数:
        	-pathname: 包括文件名的路径
        	-flags: O_WRONLY, O_RDONLY, O_RDWR, 可选项 O_APPEND  O_CREAT, 用|连接
        	-mode: 若需要创建文件,则传入要创建的文件权限,八进制 例如0664
    				最终权限是 mode&~umask
            		不同的用户的umask是不同的,直接输入umask就能查看,可以自己设置
            		umask的作用就是抹去某些权限,使得权限更加合理
    	返回值: 调用失败返回-1,否则返回文件描述符
    */
    #include <sys/types.h>
    #include <sys/stat.h>  
    #include <fcntl.h>   
    
    #include <stdio.h>
    #include <unistd.h>
    int main(){
        int fd = open("a.txt", O_RDONLY);
        if(fd == -1){
            perror("open: ");
        }
        close(fd);
        return 0;
    }
    
  3. read() 读数据

  4. write() 写数据

    /*
        #include <unistd.h>
        ssize_t read(int fd, void *buf, size_t count);
        参数:
            -fd 文件描述符,open得到的,通过这个文件描述符来操作某个文件
            -buf: 需要读取数据存放的地方,数组的地址(传出参数)
            -count: 指定的数组的大小
        读出来的数据保存到buf
        返回值: 成功返回读取到的字节数量(返回0就表示到文件的末尾了)  失败了返回-1,并且设置errno
    
        #include <unistd.h>
        ssize_t write(int fd, const void *buf, size_t count);
            -fd  文件描述符
            -buf   要往磁盘写入的数据
            -count  要写数据的实际大小
        返回值: 实际写入的字节数,失败返回-1
    */
    
    #include <unistd.h>
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    int main(){
        int src = open("create.txt", O_RDONLY);
        if(src==-1){
            perror("open:");
        }
        int destfd = open("cpy.txt", O_WRONLY | O_CREAT, 0664);
        if(destfd == -1){
            perror("open:");
        }
    
        char buf[1024] = {0};
        int len = 0;
        while((len=read(src, buf, sizeof(buf))) > 0){
            write(destfd, buf, len);
        }
    
        close(src);
        close(destfd);
        return 0;
    }
    
  5. lseek() 移动文件指针

    /*
    C库: fseek
    #include <stdio.h>
    int fseek(FILE *stream, long offset, int whence);
    
    linux lseek系统调用
        #include <sys/types.h>
        #include <unistd.h>
    
        off_t lseek(int fd, off_t offset, int whence);
        参数:
            -fd: 文件描述符
            -offset: 偏移量
            whence:  
                SEEK_SET
                    设置文件指针的偏移量(文件头开始)             
                SEEK_CUR
                  设置偏移量: 当前位置 + 第二个参数offset的值
                SEEK_END
                  设置偏移量: 文件大小(文件结尾) + 第二个参数offset的值
        返回值: 返回文件指针的位置
    
        作用: 
            移动文件指针
            获取当前文件指针的位置
            获取文件长度
            拓展文件的长度   lseek(fd, 100, SEEK_END); 移动后最好再写入一个空数据
    */
    
  6. stat()

/*
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>

    int stat(const char *pathname, struct stat *statbuf);
    作用: 获取一个文件的相关信息  可以直接使用stat a.txt在shell终端查看文件信息

    参数:
        -pathname: 操作的文件路径
        -statbuf: 结构体变量,传出参数,用于保存获取到的文件信息

    返回值: 成功返回0,失败返回-1并设置errno
    
    int lstat(const char *pathname, struct stat *statbuf);
    获取软链接的信息,否则stat获取的是软链接指向的文件的信息
*/
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
int main() {
    struct stat statbuf;
    int ret = stat("cpy.txt", &statbuf);
    if(ret == -1){
        perror("stat: ");
    }
    printf("size: %ld\n", statbuf.st_size);
    return 0;
}
posted @   预期  阅读(43)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示