文件操作

Posted hesper

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文件操作相关的知识,希望对你有一定的参考价值。

C库函数与系统函数

虚拟地址空间

Linux每一个运行的程序(进程), 操作系统都会为其飞培一个0~4G(32位操作系统)的地址空间(虚拟地址空间)

open/close

#include <unistd.h>

int close(int fd);
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

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

flags
  必选: O_RDONLY, O_WRONLY, or O_RDWR
  可选:
    O_CREAT: 创建文件时检测文件是否存在: O_EXCL, 如果存在则返回-1, 必须如O_CREAT一起使用
    O_APPEND: 追加文件
    O_TRUNC: 文件截断
    O_NONBLOCK: 设置非阻塞
mode: 权限并不是传进去的值, 而是mode & ~umask, 创建文件未指定时会随机指定一个数(垃圾值)

[email protected]:~/dir_test_1$ cat open.c 
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>


int main(int argc, const char *argv[]) {
    int fd = open("haha", O_RDWR | O_CREAT, 0777);
    if (fd == -1) {
        printf("打开失败
");
    }
 
    close(fd);

    return 0;
}
[email protected]:~/dir_test_1$ gcc open.c -o open
[email protected]:~/dir_test_1$ ./open 
[email protected]:~/dir_test_1$ ll
total 24
drwxrwxr-x  2 zyb zyb 4096 4月  10 17:12 ./
drwxr-xr-x 20 zyb zyb 4096 4月  10 17:12 ../
-rwxrwxr-x  1 zyb zyb    0 4月  10 17:12 haha*
-rwxrwxr-x  1 zyb zyb 8704 4月  10 17:12 open*
-rw-rw-r--  1 zyb zyb  269 4月  10 17:12 open.c

read

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

参数:
  fd: open的返回值
  buf: 缓冲区, 存储要读取的数据
  count: 缓冲区能存储的最大字节数sizeof(buf)
返回值:
  失败: -1
  成功: >0读出的字节数; =0文件读完了

write

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

参数:
  fd:
  buf: 要写到文件的数据
  count: strlen(buf), 文件数的有效字节数
返回值:
  失败: -1
  成功: >0写入到文件的字节数

[email protected]:~/dir_test_2$ cat read_write.c 
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>

int main(int argc, char const *argv[])
{
    // 打开一个文件
    int fd1 = open("haha.txt", O_RDWR);
    printf("fd1 = %d
", fd1);

    // 打开另外一个文件, 写操作
    int fd2 = open("hehe.txt", O_WRONLY | O_CREAT, 0664);
    printf("fd2 = %d
", fd2);

    char buf[4096];
    int len = read(fd1, buf, sizeof(buf));

    while (len > 0) {
        // 写入数据
        int ret = write(fd2, buf, len);     // 不是能用strlen(buf), strlen以为标志来判断字符串
        printf("ret = %d
", ret);
        // read
        len = read(fd1, buf, sizeof(buf));
    }

    close(fd1);
    close(fd2);

    return 0;
}
[email protected]:~/dir_test_2$ ls
haha.txt  read_write.c
[email protected]:~/dir_test_2$ gcc read_write.c -o app
[email protected]:~/dir_test_2$ ./app
fd1 = 3
fd2 = 4
ret = 4096
ret = 4096
ret = 4096
ret = 4096
ret = 4096
ret = 4096
ret = 4096
ret = 4096
ret = 4096
ret = 4096
ret = 4096
ret = 3603
[email protected]:~/dir_test_2$ ll
total 120
drwxrwxr-x  2 zyb zyb  4096 4月  10 21:57 ./
drwxr-xr-x 21 zyb zyb  4096 4月  10 21:55 ../
-rwxrwxr-x  1 zyb zyb  8872 4月  10 21:56 app*
-rw-rw-r--  1 zyb zyb 48659 4月  10 21:54 haha.txt
-rw-rw-r--  1 zyb zyb 48659 4月  10 21:57 hehe.txt
-rw-rw-r--  1 zyb zyb   647 4月  10 21:55 read_write.c

lseek

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

SEEK_SET
SEEK_CUR
SEEK_END

文件指针移动到头部: lseek(fd, 0, SEEK_SET);
获取文件指针当前位置: int len = lseek(fd, 0, SEEK_CUR);
获取文件长度: int len = lseek(fd, 0, SEEK_END);
文件拓展需要两步骤: 执行步骤1并不改变文件的大小
  1. lseek(fd, 1000, SEEK_END);
  2. 要有一次写操作write(fd, "a", 1);

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

int main(int argc, char const *argv[])
{
    // 打开一个文件
    int fd1 = open("haha.txt", O_RDWR);
    printf("fd1 = %d
", fd1);
    if (fd1 == -1) {
        perror("open");
    }   

    int len = lseek(fd1, 1000, SEEK_END);
    printf("len = %d
", len);

    write(fd1, "a", 1);

    close(fd1);

    return 0;
}

perror

errno不同值对应不同的错误信息
perror("错误信息")

以上是关于文件操作的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段15——git命令操作一个完整流程

VSCode 如何操作用户自定义代码片段(快捷键)

代码片段 - Golang 实现集合操作

Apollo Codegen 没有找到生成代码的操作或片段

VSCode自定义代码片段——.vue文件的模板

操作栏标签片段中的片段?