嵌入式学习 18(Linux高级编程——文件- 标准IO)

Linux中一切都是文件。

学习使用man指令查询函数功能:

        输入 man 命令加上要查询的函数名称,手册页将显示有关该函数的详细信息,包括函数的用途、语法、参数、返回值、示例等。手册页通常分为不同的部分,例如名称、概要、描述、返回值、错误、示例、参见等。

fopen()函数

函数原型:FILE *fopen(const char *pathname, const char *mode);

pathname表示要打开的文件;mode指定打开文件的模式。

例如:FILE * fp = fopen("1.txt","w");

FILE *fp :定义了一个指向 FILE 类型的指针 fp 。FILE 是 C 语言中用于表示文件的数据结构。

fopen("1.txt", "w") :这是一个函数调用,用于打开文件。

"w"是文件打开模式。

"1.txt" :是要打开文件的文件名。

文件打开模式:

  • "w" :以写入模式打开文件,如果文件不存在,则创建一个新文件;如果文件已存在,则清空文件内容。
  • "r" :以只读模式打开文件。如果文件不存在,则打开失败。
    例如:FILE *fp = fopen("data.txt", "r"); 用于只读方式打开 data.txt 文件。
  • "a" :以追加模式打开文件。如果文件不存在,则创建一个新文件。写入的数据会添加到文件末尾。
    比如:FILE *fp = fopen("log.txt", "a"); 可用于向日志文件追加新的记录。
  • "r+" :以读写模式打开文件。文件必须存在。
    例如:FILE *fp = fopen("file.txt", "r+"); 允许对文件进行读取和写入操作。
  • "w+" :以读写模式打开文件。如果文件不存在,则创建新文件;如果文件存在,则清空文件内容。
    比如:FILE *fp = fopen("output.txt", "w+"); 常用于创建新文件或覆盖旧文件并进行读写操作。
  • "a+" :以读写模式打开文件。如果文件不存在,则创建新文件;读取操作从文件开头开始,写入操作则添加到文件末尾。
    例如:FILE *fp = fopen("data_store.txt", "a+"); 适用于既需要读取文件已有内容,又要在末尾添加新数据的情况
#include   // 包含标准输入输出头文件

int main(int argc, char *argv[])
{
    FILE * fp = fopen("1.txt","w");  // 以只写模式打开文件"1.txt",获取文件指针
    if(NULL == fp)  // 如果文件打开失败,文件指针为 NULL
    {
        printf("fopen error\n");  // 打印"fopen error"
        return 1;  // 程序异常结束,返回 1
    }

    return 0;  // 程序正常结束,返回 0
}

fputc(写入) / fgetc(读取)

fputc() 是 C 标准库中的一个函数,用于向文件中写入一个字符。

它的函数原型为:int fputc(int c, FILE *stream)

  • c:要写入的字符。
  • stream:指向要写入的文件的 FILE 指针。

函数返回写入的字符,如果发生错误则返回 EOF(通常被定义为 -1)。

如果要依次写入字符 '1' 到 '9' :

FILE *fp = fopen("1.txt", "w");
if (fp!= NULL) 
{
    for (int i = '1'; i <= '9'; i++) 
    {
        fputc(i, fp);
    }
    fclose(fp);
}
#include   // 包含标准输入输出头文件

int main(int argc, char *argv[])
{
    FILE * fp = fopen("1.txt","w");  // 以只写模式打开文件"1.txt",获取文件指针
    if(NULL == fp)  // 如果文件打开失败,文件指针为 NULL
    {
        printf("fopen error\n");  // 打印"fopen error"
        return 1;  // 程序异常结束,返回 1
    }

    int ret = fputc('h',fp);  // 向文件中写入字符 'h',并获取返回值
    if(-1 == ret)  // 如果返回值为 -1,表示写入失败
    {
        printf("fputc error\n");  // 打印"fputc error"
        return 1;  // 程序异常结束,返回 1
    }

    fputc('e',fp);  // 向文件中写入字符 'e'
    fputc('l',fp);  // 向文件中写入字符 'l'
    fputc('l',fp);  // 向文件中写入字符 'l'
    fputc('o',fp);  // 向文件中写入字符 'o'

    fclose(fp);  // 关闭文件

    return 0;  // 程序正常结束,返回 0
}

fgetc() 是 C 标准库中的一个函数,用于从指定的文件流中读取一个字符。

它的函数原型为:int fgetc(FILE *stream)

  • stream:指向要读取的文件流的 FILE 指针。

函数返回读取到的字符,如果到达文件末尾或发生错误,则返回 EOF(通常被定义为 -1)。

#include   // 包含标准输入输出头文件

int main(int argc, char *argv[])
{
    FILE * fp = fopen("1.txt","r");  // 以只读模式打开文件"1.txt",获取文件指针
    if(NULL == fp)  // 如果文件打开失败,文件指针为 NULL
    {
        printf("fopen error\n");  // 打印"fopen error"
        return 1;  // 程序异常结束,返回 1
    }

    while(1)  // 进入一个无限循环
    {
        int c = fgetc(fp);  // 从文件中读取一个字符,并将其值赋给 c
        if(EOF == c)  // 如果读取到文件末尾(EOF)
        {
            break;  // 退出循环
        }
        printf("%c\n",c);  // 打印读取到的字符
    }

    fclose(fp);  // 关闭文件

    return 0;  // 程序正常结束,返回 0
}

 从命令行指定的源文件中读取字符,并将其逐个写入到指定的目标文件中:

#include   // 包含标准输入输出头文件

int main(int argc, char *argv[])
{
    if(argc < 3)  // 检查命令行参数的数量是否小于 3
    {
        printf("usage:./a.out srcfile dstfile\n");  // 打印使用说明
        return 1;  // 程序异常结束,返回 1
    }
    FILE *src = fopen(argv[1], "r");  // 以只读模式打开命令行参数中的第一个文件,并获取文件指针
    FILE *dst = fopen(argv[2], "w");  // 以只写模式打开命令行参数中的第二个文件,并获取文件指针
    if(NULL == src || NULL == dst)  // 如果源文件或目标文件打开失败
    {
        printf("fopen error\n");  // 打印"fopen error"
        return 1;  // 程序异常结束,返回 1
    }
    while(1)  // 进入一个无限循环
    {
        int c = fgetc(src);  // 从源文件中读取一个字符,并将其值赋给 c
        if(EOF == c)  // 如果读取到源文件末尾(EOF)
        {
            break;  // 退出循环
        }
        fputc(c, dst);  // 将读取到的字符写入到目标文件中
    }

    fclose(dst);  // 关闭目标文件
    fclose(src);  // 关闭源文件

    return 0;  // 程序正常结束,返回 0
}

fputs / fgets

fputs() 是 C 标准库中的一个函数,用于将一个字符串写入到指定的文件流中。

它的函数原型为:int fputs(const char *str, FILE *stream)

  • str:要写入的字符串。
  • stream:指向目标文件的 FILE 指针。

函数返回一个非负值表示成功写入,否则返回 EOF 表示发生错误。

fputs() 常用于将一段文本内容一次性写入文件。

#include   // 包含标准输入输出头文件

int main(int argc, char *argv[])
{
    FILE * fp = fopen("1.txt","w");  // 以只写模式打开文件"1.txt",获取文件指针
    if(NULL == fp)  // 如果文件打开失败,文件指针为 NULL
    {
        printf("fopen error\n");  // 打印"fopen error"
        return 1;  // 程序异常结束,返回 1
    }
    char data[]="hello,world";  // 定义要写入文件的字符串
    int ret = fputs(data,fp);  // 将字符串写入文件,并获取返回值
    if(EOF == ret)  // 如果返回值为 EOF,表示写入失败
    {
        printf("fputs error\n");  // 打印"fputs error"
        return 1;  // 程序异常结束,返回 1
    }
    fclose(fp);  // 关闭文件
    return 0;  // 程序正常结束,返回 0
}

fgets() 是 C 标准库中的一个函数,用于从指定的文件流中读取一行字符串。

它的函数原型为:char *fgets(char *str, int n, FILE *stream)

str:用于存储读取到的字符串的字符数组。

  • n:指定读取的最大字符数(包括字符串结束符 '\0')。
  • stream:指向要读取的文件流的 FILE 指针。

函数返回值:

  • 成功读取到一行字符串时,返回 str 。
  • 到达文件末尾或发生错误时,返回 NULL 。
#include   // 包含标准输入输出头文件

int main(int argc, char *argv[])
{
    FILE * fp = fopen("/etc/passwd","r");  // 以只读模式打开 "/etc/passwd" 文件,并获取文件指针
    if(NULL == fp)  // 如果文件打开失败,文件指针为 NULL
    {
        printf("fopen error\n");  // 打印"fopen error"
        return 1;  // 程序异常结束,返回 1
    }
    char buf[1024]={0};  // 定义一个 1024 字节的字符数组,并初始化为 0 (1k - 4k 通常是常见的缓冲区大小范围)
    while(1)  // 进入一个无限循环
    {
        char* s = fgets(buf, sizeof(buf), fp);  // 从文件中读取一行到 buf 中,并获取返回值
        if(NULL == s)  // 如果返回值为 NULL,表示已到达文件末尾或发生错误
        {
            break;  // 退出循环
        }
        printf("%s\n", buf);  // 打印读取到的这一行
    }
    fclose(fp);  // 关闭文件
    return 0;  // 程序正常结束,返回 0
}

#include   // 包含标准输入输出头文件

int main(int argc, char *argv[])
{
    FILE * fp = fopen("/etc/passwd","r");  // 以只读模式打开 "/etc/passwd" 文件,并获取文件指针
    if(NULL == fp)  // 如果文件打开失败,文件指针为 NULL
    {
        printf("fopen error\n");  // 打印"fopen error"
        return 1;  // 程序异常结束,返回 1
    }

    char buf[1024]={0};  // 定义一个 1024 字节大小的字符数组 buf,并初始化为 0
    while(1)  // 进入一个无限循环
    {
        char* s = fgets(buf, sizeof(buf), fp);  // 从文件中读取一行内容到 buf 中,并获取返回值
        if(NULL == s)  // 如果返回值为 NULL,表示已到达文件末尾或发生错误
        {
            break;  // 退出循环
        }
        printf("%s\n", buf);  // 打印读取到的这一行内容
    }

    fclose(fp);  // 关闭文件

    return 0;  // 程序正常结束,返回 0
}

        这段代码的主要作用是打开指定的文件(/etc/passwd),逐行读取文件内容并将其打印出来,直到读取到文件末尾为止。 

fwrite / fread

        fwrite 函数的原型为 size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) 。

        它的参数包括要写入的数据的指针 ptr 、每个元素的大小 size 、元素的个数 nmemb 和文件指针 stream 。如果成功,该函数返回实际写入的元素总数,这个总数是一个 size_t 类型的整型数据。如果返回值与 nmemb 参数不同,则可能表示出现了错误。

实现将一个结构体 PER 的实例数据写入到一个文件中。

#include   // 包含标准输入输出头文件
#include   // 包含字符串操作头文件

// 定义一个名为 PER 的结构体
typedef struct 
{
    char name[50];  // 用于存储名字的字符数组
    int age;  // 用于存储年龄的整数
    char phone[15];  // 用于存储电话号码的字符数组
}PER;

// 主函数
int main(int argc, char *argv[])
{
    FILE * fp = fopen("1.txt","w");  // 以写入模式打开文件"1.txt",并获取文件指针
    if(NULL == fp)  // 如果文件打开失败,文件指针为 NULL
    {
        printf("fopen error\n");  // 打印"fopen error"
        return 1;  // 返回 1 表示程序异常结束
    }
    PER per;  // 定义 PER 类型的结构体变量 per
    strcpy(per.name, "zhangsan");  // 将字符串"zhangsan"复制到 per 的 name 成员
    per.age = 20;  // 为 per 的 age 成员赋值 20
    strcpy(per.phone, "111222333");  // 将字符串"111222333"复制到 per 的 phone 成员

    size_t ret = fwrite(&per, sizeof(per), 1, fp);  // 将 per 的内容写入文件
    // 如果实际写入的个数不等于期望写入的个数 1
    if(ret!= 1)  
    {
        printf("fwrite error\n");  // 打印"fwrite error"
        return 1;  // 返回 1 表示程序异常结束
    }
    fclose(fp);  // 关闭文件
    return 0;  // 返回 0 表示程序正常结束
}

        fread函数的原型为 size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) 。

        它的第一个参数 ptr 是指向接收数据的内存地址,第二个参数 size 是每个元素的大小,第三个参数 nmemb 是要读取的元素个数,第四个参数 stream 是文件指针。

#include   // 包含标准输入输出头文件
#include   // 包含字符串处理头文件

// 定义一个名为 PER 的结构体
typedef struct 
{
    char name[50];  // 存储名字的字符数组
    int age;  // 存储年龄的整数
    char phone[15];  // 存储电话号码的字符数组
}PER;

// 主函数
int main(int argc, char *argv[])
{
    FILE * fp = fopen("1.txt","r");  // 以只读模式打开文件"1.txt",获取文件指针
    if(NULL == fp)  // 如果文件打开失败,文件指针为 NULL
    {
        printf("fopen error\n");  // 打印"fopen error"
        return 1;  // 程序异常结束,返回 1
    }
    PER per;
    // memset(&per,0,sizeof(per));  // 注释掉的这行,可用于将 per 所占据的内存初始化为 0
    bzero(&per,sizeof(per));  // 将 per 所占据的内存初始化为 0

    size_t ret = fread(&per,sizeof(per),1,fp);  // 从文件中读取一个结构体大小的数据到 per 中
    printf("name:%s age:%d phone:%s\n",per.name,per.age,per.phone);  // 打印读取到的结构体成员值
    if(ret!= 1)  // 如果实际读取的个数不等于期望读取的个数 1
    {
        printf("fread error\n");  // 打印"fread error"
        return 1;  // 程序异常结束,返回 1
    }
    fclose(fp);  // 关闭文件
    return 0;  // 程序正常结束,返回 0
}
#include 
#include 
#include 

typedef struct 
{
    char name[50];
    int age;
    char phone[15];
}PER;

int main(int argc, char *argv[])
{
    FILE * src_fp = fopen("/home/linux/1.png","r");  // 以只读模式打开源图片文件,并获取文件指针
    FILE*  dst_fp = fopen("2.png","w");  // 以只写模式创建目标图片文件,并获取文件指针
    if(NULL == src_fp || NULL == dst_fp)  // 如果源文件或目标文件打开失败
    {
        printf("fopen error\n");  // 打印"fopen error"
        return 1;  // 程序异常结束,返回 1
    }
    int size = 160743;  // 定义要读取和写入的字节数
    char *p = (char* )malloc(size);  // 动态分配内存用于存储读取的文件内容
    fread(p, size, 1, src_fp);  // 从源文件读取指定字节数的数据到分配的内存中
    fwrite(p, size, 1, dst_fp);  // 将读取的数据写入到目标文件中
    fclose(dst_fp);  // 关闭目标文件
    fclose(src_fp);  // 关闭源文件
    free(p);  // 释放动态分配的内存
    return 0;
}

        这段代码的主要功能是将一个图片文件(/home/linux/1.png)的内容读取到动态分配的内存中,然后将其写入到另一个图片文件(2.png)中。需要注意的是,在实际应用中,对于图片等二进制文件的处理,要确保文件操作的完整性和正确性,并且要注意内存的合理分配和释放,以避免内存泄漏等问题。

文件的详细描述:

例如:-rw-rw-r-- 1 linux linux 72 Aug 12 16:04 1.txt

文件信息
-rw-rw-r-- 1 linux linux 72 Aug 12 16:04 1.txt

权限解读

  • -rw-rw-r--
    • 第一个字符 - 表示这是一个普通文件。
    • rw-:文件所有者(linux)具有读(r)和写(w)权限,但没有执行(x)权限。
    • rw-:文件所属组(linux)具有读和写权限,没有执行权限。
    • r--:其他用户具有读权限,没有写和执行权限。

文件类型

  • - 普通文件
    • 文本文件,如 .txt.c.py 等。
    • 二进制文件,如可执行程序、图像文件等。
  • D 目录
    • 用于组织和存储其他文件和子目录。
  • C 字符设备
    • 像终端设备、鼠标等。
  • B 块设备
    • 例如硬盘、软盘等。
  • L 软链接(符号链接)
    • 指向另一个文件或目录的快捷方式。
  • P 管道文件
    • 用于进程间通信。
  • S 套接字文件
    • 用于网络通信。

权限表示

  • rwx rw- r—
    • 分别表示用户具有读(r)、写(w)和执行(x)权限;组用户具有读和写权限;其他人具有读权限。

八进制权限表示

  • -w- --x r— 对应的八进制数为 010 001 100,转换为十进制为 2 1 4

chmod 命令
Chmod 777 1.txt 用于更改文件 1.txt 的权限,使其对用户、组用户和其他人都具有读、写和执行权限。

硬链接
当创建硬链接时,两个文件名关联到同一个文件内容。这意味着对其中一个文件的修改会反映在另一个文件中,因为它们实际上指向相同的数据存储区域。硬链接不能跨越文件系统,且只有当所有的硬链接都被删除时,文件的数据才会真正被删除。

例如,如果有文件 file1 和它的硬链接 file2,修改 file1 的内容,在查看 file2 时会发现其内容也已更改。又如,删除 file1 时,只要 file2 还存在,文件的数据仍然保留在磁盘上。

你可能感兴趣的:(学习,c语言)