linux_文件编程

打开(open)

open函数用来打开或创建一个文件,如果成功则返回一个文件描述符fd。

参数说明

头文件

#include <sys/types.h>// 用于 mode_t,pid_t和 size_t 类型
#include <sys/stat.h> // 用于文件权限常量
#include <fcntl.h>// 用于 open 函数

函数说明

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
  • pathname: 需要打开文件的路径
  • flags:用来打开文件文件的方式
    1. O_RDONLY 只读打开
    2. O_WRONLY 只写打开
    3. O_RDWR  可读可写打开 不和O_APPEND 相与,写入多少字节就会从头开始覆盖过去
      代码:
#include <sys/types.h>// 用于 mode_t,pid_t和 size_t 类型
#include <sys/stat.h> // 用于文件权限常量
#include <fcntl.h>// 用于 open 函数
#include <stdio.h>

int main()
{
        int fd;

        fd = open("./file1",O_RDWR);// ./file1文件的路径,O_RDWR可读可写打开

        printf("fd = %d\n",fd);//打印文件描述符(成功返回一个非负整数)

        return 0;
}

结果
image.png
返回值

  • 成功时,返回一个非负整数,即文件描述符。
  • 失败时,返回 -1,并设置 errno 变量以指示错误原因。
  • 当我们附带了权限后,打开的文件就只能按照这种权限来操作。
    以上三种标志不可同时使用,但可与以下标志利用OR | 运算符组合:
    • O_CREAT 若文件不存在则创建它。使用此选项时,需要同时说明第三个参数。mode,用其说明该新文件的存取许可权限。
              – O_EXCL 如果同时指定了 OCREAT,而文件已经存在,则出错。       
              – O_APPEND 每次写时都加到文件的尾端。
              – O_TRUNC 属性去打开文件时,如果这个文件中本来是有内容的,而且为只读或只写成功打开,则将其长度截短为0。 (里面的内容都删掉,只留写入的东西)
  • mode:用来设置创建文件的权限(rwx),当flags中带有O_CREAT时才有效。(许可文件有什么权限)

没有 file1 文件,打不开所以返回值为 -1
image.png

如果文件不存在,返回值会变成 -1 ,现在写一个当文件不在的话,就创建一个

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

int main()
{
        int fd;

        fd = open("./file1",O_RDWR);//打开文件,没有文件返回 -1(文件描述符)

        if(fd == -1){//判断有没有文件
                printf("open file1 failed\n");//打开文件失败打印
                fd = open("./file1",O_RDWR|O_CREAT,0600);//没有文件就在./file1路径创建一个,文件权限为可读可写
                if(fd > 0){//创建成功,返回值大于0
                        printf("create file1 success\n");
                }
        }
        return 0;
}
image.png

权限:

image.png

一共有10位数
其中: 最前面那个 – 代表的是类型
中间那三个 rw- 代表的是所有者(user)
然后那三个 rw- 代表的是组群(group)
最后那三个 r– 代表的是其他人(other)

r 表示文件可以被读(read)
w 表示文件可以被写(write)
x 表示文件可以被执行(如果它是程序的话)

rwx也可以用数字来代替
r ————4
w ———–2
x ————1

0600
0 –>代表十进制
6 –> 4 + 2 + 0 = 6 可读可写 所有者的权限
0 –> 组群 的权限
0 –> 其他人 的权限

写入(write)

write函数的头文件

#include <unistd.h>

writr函数的格式原型:

ssize_t write(int fd, const void *count, size_t count);
//write() 函数会从指针 buf 所指向的缓冲区中读取最多 count 个字节,并将其写入由文件描述符 fd 指定的文件中。

int fd –> open的返回值(文件描述符)
const void *count –> 无类型的指针,作为缓冲区来写入/读取文件
size_t count –> 写入文件的大小

wirte函数返回值
写入成功,返回值为写入成功的字节数
写入失败,返回值为 -1

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>//write和close的头文件
#include <string.h>//strlen

int main()
{
    int fd;
    char *buf = "xiaolong hen shuai!";//写入的内容

    fd = open("./file1",O_RDWR);

    if(fd == -1){
        printf("open file1 failed\n");
        fd = open("./file1",O_RDWR|O_CREAT,0600);
        if(fd > 0){
            printf("create file1 success\n");
        }
    }
    printf("open susceess : fd = %d\n",fd);

    write(fd,buf,strlen(buf));
    //write(int fd, const void *count, size_t count);//write() 函数会从指针 buf 所指向的缓冲区中读取最多 count 个字节,并将其写入由文件描述符 fd 指定的文件中。

    close(fd);//要关闭的文件,将对应的fd(文件描述符)写进里面

    return 0;
}
image.png

strlen (函数)

函数用于计算字符串的长度(不包括结尾的空字符’\0’)

strlen的头文件

#include <string.h>  // 必须包含的头文件
#include <string.h>  // 必须包含的头文件
int main() {
    const char *str = "HelloWorld";//10个英文
    size_t length = strlen(str);  // 计算字符串长度

    printf("字符串长度: %zu\n", length);  // 输出:10,不包括结尾的空字符'\0'
    return 0;
}
image.png
特性说明
返回值类型size_t(无符号整型,用 %zu 打印)
计算范围从字符串起始到第一个 \0 前的字符数
不包含结尾的空字符 \0

关闭 (Close)

close函数的头文件

#include <unistd.h>

close函数的格式原型:

int close(int fd);

int fd –> 写入需要关闭的文件,将对应的fd(文件描述符)写进里面

重点:

  • writr函数的格式原型:
ssize_t write(int fd, const void *count, size_t count);
//write() 函数会从指针 buf 所指向的缓冲区中读取最多 count 个字节,并将其写入由文件描述符 fd 指定的文件中。
  • close函数的格式原型:
int close(int fd);

int fd –> 写入需要关闭的文件,将对应的fd(文件描述符)写进里面

读取 (read)

read函数的头文件

#include <unistd.h>

read函数的格式原型:

ssize_t read(int fd, void buf[.count], size_t count);

描述 read() 函数尝试从文件描述符 fd 中读取最多 count 个字节的数据,并将其存储在从 buf 开始的缓冲区中

malloc函数 (动态分配内存空间)

在 C 语言中,malloc 函数用于动态分配内存空间,它在程序运行时从堆(heap)中申请指定大小的内存。

基本用法

头文件

#include <stdlib.h> // 必须包含此头文件

函数原型

void* malloc(size_t size);//空类型指针
  • 参数size 是要分配的字节数。
  • 返回值
    • 成功:返回指向分配内存起始地址的 void* 指针
    • 失败:返回 NULL

使用步骤

  1. 计算所需内存大小(通常用 sizeof
  2. 调用 malloc 分配内存
  3. 检查指针是否为 NULL(分配失败处理)
  4. 使用分配的内存
  5. 释放内存(必须用 free() 避免内存泄漏)

示例代码

分配单个整型

#include <stdio.h>
#include <stdlib.h>

int main() {
    // 动态分配一个 int 类型的内存空间
    int* ptr = (int*)malloc(sizeof(int));

    // 检查分配是否成功
    if (ptr == NULL) {
        printf("内存分配失败!\n");
        return 1; // 退出程序
    }

    *ptr = 100; // 向分配的内存写入数据
    printf("值 = %d\n", *ptr);

    free(ptr); // 释放内存
    ptr = NULL; // 避免悬空指针(可选但推荐)
    return 0;
}

1. 类型转换(C++ 中必须,C 中可选但推荐):

int* ptr = (int*)malloc(sizeof(int)); // C/C++ 通用写法

2. 计算内存大小

  • 使用 sizeof 而非直接写数字(保证可移植性):
// 推荐
int* arr = malloc(10 * sizeof(int));

// 避免(硬编码大小)
int* arr = malloc(40); // 假设 int 占 4 字节(不通用!)

read返回0和读取的东西为空,因为写东西进里面的时候,写完光标在最后了,不会返回前面,所以读取到的东西就为0和空了
image.png
解决办法 //关闭,重新打开

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>//write和close的头文件
#include <string.h>//strlen
#include <stdlib.h>

int main()
{
        int fd;//定义一个变量来接收返回值
        char *buf = "xiaolong hen shuai!";//定义一个指向char型的指针

        fd = open("./file1",O_RDWR);

        if(fd == -1){
                printf("open file1 failed\n");
                fd = open("./file1",O_RDWR|O_CREAT,0600);
                if(fd > 0){
                        printf("create file1 success\n");
                }
        }
        printf("open susceess : fd = %d\n",fd);

        int n_write = write(fd,buf,strlen(buf));
        if(n_write != -1){
                printf("write %d byte to file\n",n_write);
        }
        close(fd);//关闭

        fd = open("./file1",O_RDWR);//重新打开


        char *readBuf;
        readBuf = (char *)malloc(sizeof(char)*n_write + 1);//这行代码动态分配了n_write + 1 字节的内存空间,用于存储一个以&nbsp;'\0'&nbsp;结尾的字符串,其中前&nbsp;n_write&nbsp;字节存放有效字符,最后 1 字节存放字符串结束符。

        int n_read = read(fd, readBuf, n_write); //read() 函数尝试从文件描述符 fd 中读取最多 count 个字节的数据,并将其存储在从 buf 开始的缓冲区中

        printf("read %d ,context:%s\n",n_read,readBuf);
        close(fd);

        return 0;
}
image.png

重点

  • 描述 read() 函数尝试从文件描述符 fd 中读取最多 count 个字节的数据,并将其存储在从 buf 开始的缓冲区中
  • 读取成功会返回读取的字节数
  • 读取错误会返回 -1
  • 函数原型 上面查看

文件光标移动操作

image.png

头文件

#include <unistd.h>

函数原型

off_t lseek(int fd, off_t offset, int whence);//以文件描述符来选择对应哪个文件,在文件里以 whence 方式来定义 offset 偏移数值(可正负偏移) 

offset(偏移量)

  • 可以正负偏移

whence的方式(哪个位置放置光标)

  1. SEEK_SET :在最前面放置光标
  2. SEEK_CUR :在当前位置放置光标
  3. SEEK_END :在末尾放置光标

代码

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>//write和close的头文件
#include <string.h>//strlen
#include <stdlib.h>

int main()
{
        int fd;//定义一个变量来接收返回值
        char *buf = "xiaolong hen shuai!";//定义一个指向char型的指针

        fd = open("./file1",O_RDWR);

        if(fd == -1){
                printf("open file1 failed\n");
                fd = open("./file1",O_RDWR|O_CREAT,0600);
                if(fd > 0){
                        printf("create file1 success\n");
                }
        }
        printf("open susceess : fd = %d\n",fd);

        int n_write = write(fd,buf,strlen(buf));
        if(n_write != -1){
                printf("write %d byte to file\n",n_write);
        }
        close(fd);//关闭

        fd = open("./file1",O_RDWR);//重新打开


        lseek(fd, 0,SEEK_SET);//在最前面放置光标,偏移0

        char *readBuf;
        readBuf = (char *)malloc(sizeof(char)*n_write + 1);//这行代码动态分配了n_write + 1 字节的内存空间,用于存储一个以&nbsp;'\0'&nbsp;结尾的字符串,其中前&nbsp;n_write&nbsp;字节存放有效字符,最后 1 字节存放字符串结束符。

        int n_read = read(fd, readBuf, n_write); //read() 函数尝试从文件描述符 fd 中读取最多 count 个字节的数据,并将其存储在从 buf 开始的缓冲区中

        printf("read %d ,context:%s\n",n_read,readBuf);
        close(fd);

        return 0;
}

创建文件(creat)

image.png

open 一样操作,一样要重新写 fd

文件操作指令,实现 cp 指令

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>//write和close的头文件
#include <string.h>//strlen
#include <stdlib.h>

int main(int argc, char **argv)
{
    int fdSrc;//需要复制的文件
    int fdDes;//复制出来的文件
    char *readBuf = NULL;//读写的指针

    if(argc != 3)//参数个数不等于3
    {
            printf("patatm error\n");
            exit(-1);//退出
    }

    fdSrc = open(argv[1], O_RDWR);//获取文件描述符fd
    int size = lseek(fdSrc,0,SEEK_END);//获取文件的字节来准备缓存空间
    lseek(fdSrc,0,SEEK_SET);//光标放置最前面

    readBuf = (char *)malloc(sizeof(char)*size + 8);//分配以size+8的动态内存的大小给readBuf

    int n_read = read(fdSrc, readBuf, size);//读取fdSrc的内容放在readBuf里面,并返回读到的字节个数

    fdDes = open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0600);//创建一个新的文件

    int n_write = write(fdDes,readBuf,strlen(readBuf));//写读到readBuf的东西给fdDes
    close(fdSrc);//关闭fdSrc
    close(fdDes);//关闭fdDes

    return 0;
}

命令行参数 char **argv

int main(int argc, char **argv) {
    // argv[0] → 程序名 (char*)
    // argv[1] → 第一个参数 (char*)
    for (int i = 0; i < argc; i++) 
        printf("参数 %d: %s\n", i, argv[i]);
    return 0;
}

文件编程小应用之修改程序配置文件

strstr函数

strstr 是 C 语言中用于查找子字符串的标准库函数,它像一个“字符串探测器”。(在指定文件里面寻找需要修改的字符)

#include <string.h>  // 必须包含头文件

char *strstr(const char *haystack, const char *needle);
  • haystack:主字符串(干草堆)
  • needle:要查找的子字符串(针)
  • 返回值:指向 主字符串 中子串首次出现的指针

修改配置程序

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>//write和close的头文件
#include <string.h>//strlen
#include <stdlib.h>

int main(int argc, char **argv)
{
    int fdSrc;
    char *readBuf = NULL;

    if(argc != 2)
    {
            printf("patatm error\n");
            exit(-1);
    }

    fdSrc = open(argv[1], O_RDWR);
    int size = lseek(fdSrc,0,SEEK_END);
    lseek(fdSrc,0,SEEK_SET);

    readBuf = (char *)malloc(sizeof(char)*size + 8);

    int n_read = read(fdSrc, readBuf, size);

    char *p = strstr(readBuf, "LENG=");//在&nbsp;`readBuf`&nbsp;字符串中搜索子串&nbsp;`"LENG="`
    if(p == NULL){
            printf("not found\n");
            exit(-1);
            }

    p = p + strlen("LENG=");//读取 LENG= 的个数 + p  
    *p = '5';//将光标位置的内容改为 5

    lseek(fdSrc,0,SEEK_SET);
    int n_write = write(fdSrc,readBuf,strlen(readBuf));

    close(fdSrc);
//      close(fdDes);


    return 0;
}

写一个整数到文件

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>//write和close的头文件
#include <string.h>//strlen
#include <stdlib.h>

int main()
{
        int fd;

        int data = 100;
        int data2 = 0;

        fd = open("./file1",O_RDWR);

        int n_write = write(fd, &data, sizeof(int));//写整数到file1文件里,之间取data地址的内容写进里面

        lseek(fd, 0, SEEK_SET);//写完,光标放在最前面

        int n_read = read(fd, &data2, sizeof(int));//将东西读取放到data2里面

        printf("read %d \n",data2);

        close(fd);

        return 0;
}

写结构体数组到文件

单个结构体

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>//write和close的头文件
#include <string.h>//strlen
#include <stdlib.h>

struct Test
{
        int a;
        int c;
};

int main()
{
        int fd;

        struct Test data = {100,'a'};//初始化
        struct Test data2;

        fd = open("./file1",O_RDWR);

        int n_write = write(fd, &data, sizeof(struct Test));//将data的内容写到file1文件里,

        lseek(fd, 0, SEEK_SET);

        int n_read = read(fd, &data2, sizeof(struct Test));//以struct Test的大小来读fd(文件描述符)所指的文件存储到 data2的地址里面

        printf("read %d,%c \n",data2.a,data2.c);

        close(fd);

        return 0;
}

两个结构体

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>//write和close的头文件
#include <string.h>//strlen
#include <stdlib.h>

struct Test
{
        int a;
        int c;
};

int main()
{
        int fd;

        struct Test data[2] = {{100,'a'},{101,'b'}};//定义结构体数组
        struct Test data2[2];

        fd = open("./file1",O_RDWR);

        int n_write = write(fd, &data, sizeof(struct Test)*2);

        lseek(fd, 0, SEEK_SET);

        int n_read = read(fd, &data2, sizeof(struct Test)*2);

        printf("read %d,%c \n",data2[0].a,data2[0].c);
        printf("read %d,%c \n",data2[1].a,data2[1].c);

        close(fd);

        return 0;
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇