Linux C语言文件操作:从标准IO到文件IO的全面解析

【C 语言】文件操作实战:从 fopen 模式选择到跨平台数据读写 本文深入探讨C语言文件操作的核心技巧,从fopen模式选择到跨平台数据读写实战。通过分析r/w/a模式差异、二进制与文本模式对比,以及错误处理和性能优化策略,帮助开发者掌握高效可靠的文件操作方法。特别针对嵌入式开发和跨平台场景,提供了实用的解决方案和最佳实践。 阅读详情

一、Linux文件操作概述

在Linux系统编程中,文件操作是核心技能之一。理解文件操作的本质,需要先明确内存与外存的区别:

  • 内存(变量、数组、数据结构):
    • 读写数据速度快
    • 程序执行结束、掉电后数据丢失
    • 空间小,价格昂贵
  • 文件(外存/硬盘):
    • 读写速度比内存慢
    • 掉电后数据不丢失
    • 空间大,相对内存价格便宜

文件的主要作用有两个:一是长期保存掉电不丢失的数据;二是作为Linux提供给应用层的硬件操作接口,体现了“一切皆文件”的设计哲学。

二、Linux下的文件类型

Linux系统将一切资源都抽象为文件,通过ls -l 文件名命令可以查看文件的详细信息。文件类型由输出行首的第一个字符标识:

  • b:块设备文件(block),如硬盘等存储设备----->文件IO
  • c:字符设备文件(character),如鼠标、键盘、显示器----->文件IO
  • d:目录文件(directory),如文件夹----->目录IO
  • -:普通文件(regular file),如main.c、xxx.txt、a.out----->文件IO,标准IO
  • l:软连接文件(link),相当于快捷方式(符号链接)----->链接项
  • s:套接字文件(socket),用于网络编程----->文件IO
  • p:管道文件(pipe),用于进程间通信----->文件IO

三、Linux文件操作方法

Linux下的文件操作主要分为两类:

  1. 标准IO:标准C库提供的文件操作接口,属于库函数
  2. 文件IO:Linux内核提供的文件操作接口,属于系统调用

无论使用哪种方法,文件操作的基本思想都是相同的:

  1. 打开文件
  2. 读文件、写文件
  3. 关闭文件

四、标准IO操作详解

4.1 打开文件:fopen()

#include <stdio.h>

FILE *fopen(const char *pathname, const char *mode);

功能:打开一个文件,并获得一个文件流指针

参数:

  • pathname:要打开的文件的文件名
  • mode:打开方式
    • "r":以只读方式打开,文件必须要存在
    • "r+":以读写方式打开,文件必须要存在
    • "w":以只写方式打开,文件不存在则创建,文件存在则清空
    • "w+":以读写方式打开,文件不存在则创建,文件存在则清空
    • "a":以只写方式打开,文件不存在则创建,写时追加写
    • "a+":以读写方式打开,文件不存在则创建,读从开头读,写从末尾写

返回值:

  • 成功:FILE*(文件流指针)
  • 失败:NULL

4.2 关闭文件:fclose()

int fclose(FILE *stream);

功能:关闭文件

参数:stream:已打开的文件的文件流指针

返回值:

  • 成功:0
  • 失败:EOF(-1)

注意:只打开文件而使用完不关闭文件,会造成文件描述符泄露。只有 fclose(或 fflush)之后,数据才会从“用户态缓冲区”强制输出到“内核缓冲区”(即操作系统管理的页缓存),从而让其他打开的文件流能够看到它。

4.3 标准流

操作系统默认已打开的三个标准流:

  • stdin:标准输入流,对应标准输入设备(键盘)
  • stdout:标准输出流,对应标准输出设备(显示屏/终端)
  • stderr:标准出错流,对应标准出错设备(显示屏/终端)

4.4 字符读写:fputc()和fgetc()

int fputc(int c, FILE *stream);
功能:向文件中写入一个字符
参数:
c:要写入的字符或者字符对应的ASCII值
stream:要写入的文件的文件流指针
返回值:
成功:写入的字符
失败:EOF(-1)
注意:putchar('a'); ===> fputc('a', stdout)
int fgetc(FILE *stream);
功能:从文件中读取一个字符
参数:
stream:要读取的文件的文件流指针
返回值:
成功:返回读到的字符
失败:EOF(-1)
读到文件末尾:EOF(-1)

4.5 字符串读写:fputs()和fgets()

int fputs(const char *s, FILE *stream);

功能:将一个字符串写入到文件,不包括'\0'字符

参数:
s:要写入的字符串的首地址
stream:要写入的文件的文件流指针
返回值:
成功:>=0
失败:EOF(-1)
char *fgets(char *s, int size, FILE *stream);
功能:从文件中读取一行,遇到新行结束, 会读取 \n,但遇到 \n 就停止读取,并把 \n 存入缓冲区,末尾自动补 \0,读到 \n 或缓冲区满就停。
参数:
s:存储读取到的数据的空间首地址
size:期待读到的字节数(最多size-1,留空间给\0,每次指针从上次读取的位置继续)
buff[strlen(buff)-1] = 0;    //给\n的位置设为0
buff[strcspn(buff, "\n")] = 0;//可用于使用fgets在终端读取字符串并去掉末位\n
//strcspn函数在buff中找到\n的下标
stream:要读的文件的文件流指针
返回值:
成功:返回s,存储数据的空间首地址
失败:NULL
到达文件末尾:NULL

4.6fwrite与fread

size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);

功能:向文件中写入大小是size的nmemb个元素
参数:
ptr:要写入的元素的首地址
size:每个元素的字节数
nmemb:要写入的元素的个数
stream:要写入的文件流指针
返回值:
成功:实际写入的元素个数
失败:< nmemb

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

功能:从文件中读取大小是size的nmemb个元素到ptr指针指向的内存空间,读取\n,不加\0,读满指定个数或 EOF
参数:
        ptr:用来存储读到数据的空间首地址
        size:每个元素的字节数
        nmemb:希望读取的元素个数
        stream:要读的文件流指针
返回值:
        成功:返回实际从文件中读到的元素个数
当文件中不足一个元素时,返回0

size与nmemb不可交换,否则可能出现当读取数据不足一个元素时返回0;

4.7流定位函数

fseek()

int fseek(FILE *stream, long offset, int whence);

功能:重新定位流的位置
参数:
        stream:要定位的文件流指针
        offset:偏移量(字节)
        whence:要偏移的相对位置
        SEEK_SET : 从文件开头偏移
        SEEK_CUR :从当前位置偏移
        SEEK_END :从文件末尾偏移
返回值:
        成功:0
        失败:-1

抢占磁盘空间
创建空洞文件,提前抢占磁盘空间,加'\0'才可,不然只移动光标不会预分配空间

ftell()

long ftell(FILE *stream);

功能:获取流所在位置到文件开头的偏移量

rewind()

void rewind(FILE *stream);

功能:将流复位到开头

  • 求文件大小
fseek(fp, 0, SEEK_END);
len = ftell(fp);
rewind(fp);

五、时间相关函数

time()

#include <time.h>
time_t time(time_t *tloc);
功能:获取1970-1-1 00:00:00到现在的秒数
参数:
        tloc:保存秒数的变量的地址
返回值:
        获得的秒数

两种用法:

time_t now = time(NULL);   // 1.直接赋值给变量

time_t now;                // 2.秒数直接被写入 now 的地址中
time(&now);
// 或者同时用返回值(虽然很少这么干)
time_t ret = time(&now);   // ret 和 now 的值相等

ctime()

char *ctime(const time_t *timep);
功能:将秒数转换成字符串时间
参数:
        timep :秒数的变量的地址
返回值:
        字符串时间

localtiome()

struct tm *localtime(const time_t *timep);
功能:将秒数转换成日历时间
struct tm {
int tm_sec; /* Seconds (0-60) */
int tm_min; /* Minutes (0-59) */
int tm_hour; /* Hours (0-23) */
int tm_mday; /* Day of the month (1-31) */
int tm_mon; /* Month (0-11) */
int tm_year; /* Year - 1900 */
int tm_wday; /* Day of the week (0-6, Sunday = 0) */
int tm_yday; /* Day in the year (0-365, 1 Jan = 0) */
int tm_isdst; /* Daylight saving time */
};

用法:

struct tm mtim = *localtime(&now);    //用struct tm结构体接收返回的结构体值,now为由time获得的秒数

    六、文件IO

    文件IO是Linux内核提供的文件操作接口,属于系统调用。与标准IO相比,文件IO直接使用文件描述符进行操作。

    6.1 打开文件:open()

    #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);

    功能:打开一个文件并获得一个文件描述符

    参数:

    • pathname:要打开的文件的文件名
    • flags:打开方式
      • O_RDONLY:只读
      • O_WRONLY:只写
      • O_RDWR:读写
      • O_CREAT:创建
      • O_TRUNC:清空
      • O_APPEND:追加
    • mode:用户自己、同组用户、其他用户对该文件的读写执行权限,实际权限是mode&~umask,umask本电脑为0002;(umask命令可直接查看)
      • 普通文件:0664
      • 权限给满:0777

    注意:当采用O_CREAT创建文件时需要加权限,否则即使加了内核也会忽略

    返回值:

    • 成功:文件描述符
    • 失败:-1

    6.2 关闭文件:close()

    #include <unistd.h>
    
    int close(int fd);

    功能:关闭文件

    参数:fd:文件描述符

    返回值:

    • 成功:0
    • 失败:-1

    注意:只打开文件,使用完不关闭文件会造成文件描述符泄露。

    6.3 文件描述符

    当打开一个文件时,系统会为已打开的文件分配一个文件描述符用来标记该文件。文件描述符是小的、非负的整型数据。

    操作系统默认可分配出的文件描述符:0-1023,总共1024个。文件描述符的分配原则:最小未被使用。

    系统默认已打开的文件:

    标准IO文件IO
    FILE*int
    stdin0(STDIN_FILENO)
    stdout1(STDOUT_FILENO)
    stderr2(STDERR_FILENO)

    6.4 读写文件:write()和read()

    ssize_t write(int fd, const void *buf, size_t count);
    ssize_t read(int fd, void *buf, size_t count);

    write()功能:向文件中写入数据,写入数据用strlen,否则会多写入无用数据,可用size接收read的返回值进行写入。

    read()功能:从文件中读取数据,包括\n自动覆盖buff里的内容,若读取为空则返回0,不会覆盖也不会清空buff,只管数量,不管内容(包括\0),一直读到 count 个字节或 EOF。

    read与write配合使用

    while((size = read(fd,buff,sizeof(buff)))>0)
    {
        write(fdfifo, buff, size);
    }

    read与fread都是二进制函数,前者无缓冲,后者有缓冲,都可读取图片。

    返回值:

    • 成功:实际写入/读取的字节数
    • 失败:-1
    • 到达文件末尾(read):0

    6.5 文件定位:lseek()

    off_t lseek(int fd, off_t offset, int whence);

    功能:重新定位文件的读写位置

    参数:

    • fd:文件描述符
    • offset:偏移量
    • whence:要偏移的起始位置
      • SEEK_SET:从文件开头偏移
      • SEEK_CUR:从当前读写位置偏移
      • SEEK_END:从文件末尾偏移

    返回值:

    • 成功:返回当前读写位置到文件开头的偏移量
    • 失败:-1

    6.6 文件拷贝示例

    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    
    int file_copy(const char *srcfile, const char *dstfile)
    {
        int fdsrc = open(srcfile, O_RDONLY);
        int fddst = open(dstfile, O_WRONLY | O_CREAT | O_TRUNC, 0664);
        
        if (-1 == fdsrc || -1 == fddst)
        {
            printf("open error\n");
            return -1;
        }
        
        char buff[1024] = {0};
        ssize_t size = 0;
        while ((size = read(fdsrc, buff, sizeof(buff))) > 0)
        {
            write(fddst, buff, size);
        }
        
        close(fdsrc);
        close(fddst);
        return 0;
    }

    七、文件IO和标准IO的区别

    文件IO和标准IO在Linux文件操作中各有特点,主要区别如下:

    特性标准IO文件IO
    操作对象FILE*(文件流指针)fd(文件描述符)
    来源标准C库函数Linux系统调用
    可移植性强(跨平台)弱(Linux特有)
    缓冲区有缓冲区无缓冲区
    效率减少用户层和内核层反复切换,提高效率实时性好
    适用场景主要用在对普通文件操作普通文件、硬件设备类相关的文件

     优先选择“标准I/O”的场景(90%的日常代码)

    1. 你需要处理“文本”和“格式化”数据

      比如写日志(fprintf)、读配置文件、拼接字符串(sprintf)。标准I/O 提供的 fprintf、fscanf、fgets 能让你一行代码搞定格式化,用文件I/O(read)你得手动解析二进制,非常痛苦。
    2. 你需要跨平台(Windows / Linux / macOS)

      标准I/O 是C标准库的一部分,在任何操作系统上行为一致。而文件I/O(open/read)是POSIX标准,在Windows上不直接支持(需要用 CreateFile / ReadFile)。
    3. 你操作的是“普通磁盘文件”,且数据量不大(GB级别以下)

      标准I/O 自带用户态缓冲区,能有效减少系统调用次数。多数情况下,它的性能已经足够好,且代码写起来更安全。
    4. 你需要按“行”读取数据

      比如处理 CSV、日志文件,fgets 一行一行读既安全又简单。用 read 你需要自己处理 \n 的分割,容易写出bug。

    必须选用“文件I/O(系统调用)”的场景

    1. 你需要实现“非阻塞I/O”或“异步I/O”

      标准I/O(FILE*)默认是阻塞的,且无法与 select、poll、epoll 配合。如果你在写网络服务器或高并发程序,必须用 open/read/write 搭配 O_NONBLOCK 标志。
    2. 你需要精确控制“数据落盘”时机

      标准I/O 的 fclose 或 fflush 只保证数据从用户态缓冲区到了内核缓冲区(页缓存),不保证写到磁盘。如果你需要确保持久化(比如数据库日志),必须用系统调用 fsync 或 O_SYNC 配合文件描述符。
    3. 你需要操作“大文件”或“裸设备”

      标准I/O 的缓冲区策略在某些极端大文件场景下可能造成内存压力。文件I/O 允许你直接指定 O_DIRECT 绕过页缓存,实现用户态直接I/O(虽然限制较多)。
    4. 你需要操作“非普通文件”

      比如管道(pipe)、Socket(套接字)、设备文件(/dev/xxx)。虽然标准I/O 也能打开它们,但往往会因为缓冲模式不匹配(如行缓冲/全缓冲)导致数据延迟或阻塞异常,系统调用在这些场景下更可控。
    5. 你要实现“文件锁”或“高级控制”

      比如 fcntl 锁、ioctl 控制设备,这些操作只支持文件描述符(int fd),不支持 FILE*。

    7.1 缓冲区类型

    标准IO使用缓冲区机制,主要分为三种类型:

    1. 行缓冲

    • 默认大小1024字节(1K)
    • 主要使用在人机交互终端上,标准输出 stdout(当输出目标是终端/屏幕时)
    • 刷新条件:
      • 遇到'\n'刷新
      • 程序结束刷新
      • 使用fflush()强制刷新
      • 缓冲区满时自动刷新

    2. 全缓冲

    • 默认大小4096字节(4K)
    • 主要用于文件交互,文件流(fopen 打开的文件)
    • 刷新条件:
      • 程序结束刷新
      • 文件关闭自动刷新
      • 全缓冲区满时自动刷新
      • 使用fflush()强制刷新

    3. 无缓冲

    • 0K
    • 主要用于出错信息输出,标准出错设备stderr

    7.2 打开方式对应关系

    标准IO与文件IO的打开方式对应关系:

    • "r" → O_RDONLY
    • "r+" → O_RDWR
    • "w" → O_WRONLY | O_TRUNC | O_CREAT,0664
    • "w+" → O_RDWR | O_TRUNC | O_CREAT,0664
    • "a" → O_WRONLY | O_CREAT | O_APPEND,0664
    • "a+" → O_RDWR | O_CREAT | O_APPEND,0664

    八、目录IO

    • opendir

    DIR *opendir(const char name);

    功能:打开目录文件并获得目录流指针
    参数:
            name:目录名
    返回值:
            失败:NULL
            成功:目录流指针

    • closedir

    int closedir(DIR *dirp);

    功能:关闭目录文件
    参数:
            dirpr 目录流指针
    返回值:
            成功:0
            失败:-1

    • readdir

    struct dirent *readdir(DIR* dirp);

    参数:
            dirp:目录流指针
    返回值:
            失败:NULL
            成功:struct dirent 指针,代表读到的文件信息,读取后指针自动加一到下一个文件。
            文件末尾:NULL

    struct dirent {
    ino_t    d_ino;    //Inode number 
    off_t    d_off;    //Not an offset; see below 
    
    unsigned short d_reclen;    // Length of this record 
    unsigned char d_type;       // Type of file; not supported by all filesystem types 
    
    char    d_name[256];        // Null-terminated filename 
    }

    ls -i        查看ino号

    ls -a        查看隐藏文件(.和..)

    九、其他

    1、输出流

    int fprintf(FILE *stream, const char *format, ...);
    功能:将格式化后的字符串写入到stream文件流代表的文件中。(文件)
    int dprintf(int fd, const char *format, ...);
    功能:将格式化后的字符串写入到fd所代表的文件中。
    *int sprintf(char *str, const char *format, ...);
    功能:将格式化后的字符串写入到字符型数组中(内存)
    字符串的拼接,格式化
    可以将整形数据、浮点型数据等转换成字符串
    函数目标对象数据类型核心场景
    printf标准输出(屏幕)FILE*(stdout)默认终端打印
    fprintf任何文件流(如 fopen 返回的指针)FILE*(如 fp、stderr)写入文件、写入错误输出
    dprinf文件描述符(如 open 返回的整数)int fd(如 STDOUT_FILENO、fd)系统调用级别的直接写入,无缓冲区卡顿
    sprinf内存缓冲区(char[] 数组)char*拼字符串,做网络包,存到变量里
    char *strtok(char *str, const char *delim);
    功能:字符串截取函数
    参数:
    str:要截取的原始字符串
    delim:要截断的分隔符
    返回值:
    成功:截取到的子字符串的首地址
    失败:NULL(已经到字符串末尾)
    注意:strtok会破坏原字符串。 它会把找到的分隔符位置替换成 \0(字符串结束符),从而把原字符串切分成多个子串。

    2.实战示例

    1) 使用fgetc读取文件内容

    #include <stdio.h>
    
    int main(int argc, const char *argv[])
    {
        if (argc < 2)
        {
            printf("Usage : ./a.out <filename>\n");
            return -1;
        }
        
        FILE *fp = fopen(argv[1], "r");
        if (NULL == fp)
        {
            printf("fopen error\n");
            return -1;
        }
        
        int ch;
        while ((ch = fgetc(fp)) != EOF)
        {
            putchar(ch);
        }
        
        fclose(fp);
        return 0;
    }

    2) 实现cp命令功能

    #include <stdio.h>
    
    int main(int argc, const char *argv[])
    {
        if (argc < 3)
        {
            printf("Usage: ./a.out srcfile dstfile\n");
            return -1;
        }
        
        FILE *fpsrc = fopen(argv[1], "r");
        FILE *fpdst = fopen(argv[2], "w");
        
        if (NULL == fpsrc || NULL == fpdst)
        {
            printf("fopen error\n");
            return -1;
        }
        
        int ret = 0;
        while (1)
        {
            ret = fgetc(fpsrc);
            if (EOF == ret)
            {
                break;
            }
            fputc(ret, fpdst);
        }
        
        fclose(fpsrc);
        fclose(fpdst);
        return 0;
    }

    3、主函数传参

    可以在程序运行时,利用命令行参数向主函数传参:

    int main(int argc, const char *argv[])
    {
        // argc:命令行传递的参数个数
        // argv:保存多个char*类型指针的数组
        // argv[0] ----> "./mycat"
        // argv[1] ----> "1.txt"
        // argv[2] ----> "aaa"
        // ...
    }

    示例:执行./mycat 1.txt aaa bbb ccc时:

    • argc = 4
    • argv[0] = "./mycat"
    • argv[1] = "1.txt"
    • argv[2] = "aaa"
    • argv[3] = "bbb"
    • argv[4] = "ccc"

    4、man手册使用

    Linux提供了完善的man手册系统,帮助开发者查阅文档:

    • Linux命令:man ls或man 1 ls
    • 系统调用:man open或man 2 open
    • 库函数:man fopen、man fread、man fclose

    5.创建目录

    int mkdir(const char *pathname, mode_t mode);
    功能:创建一个目录文件(文件夹)
    参数:
         pathname:目录名称
         mode:目录文件的操作权限
    返回值:
         成功:0
         失败:-1

    6.出错处理函数

    • strerror

    char *strerror(int errnum);
    功能:将错误码转换成对应的错误信息字符串
    参数:
        errnum:错误码:errno
    返回值:
         失败:NULL
        成功:返回错误码对应的字符串首地址

    • perror

    void perror(const char *s);
    功能:打印自己的出错处理信息和系统系统给出的出错原因。

    当调用 perror("open") 时,它做了三件事:

    1. 获取当前的 errno 值。(全局变量errno,当 open、read、malloc 等系统调用或库函数执行失败时,Linux 内核(或 glibc 库)会自动将一个特定的数字写入 errno。)

    2. 调用 strerror(errno) 拿到字符串 "No such file or directory"。

    3. 把 传入的字符串 "open" + 冒号空格 + 错误描述字符串 一起输出到标准错误(stderr)。

    十、framebuffer

    1.什么是framebuffer

    帧缓存、帧缓冲技术。
    是Linux为显示设备提供的一个接口,把显存抽象后的一种设备,通过该设备文件可以实现应用层向显存空间的数据写入,从而实现像素点的绘制。

    2.如何操作framebuffer

    通过内存映射技术,可以实现显存空间和用户空间的内存映射,通过向用户空间写入RGB颜色值,从而实现显存数据的写入。

    1.打开显示设备文件/dev/fb0
    2.获取显示设备相关参数:分辨率、像素点的位数(位深度)
    3.建立内存映射
    4.写入RGB颜色值
    5.解除内存映射
    6.关闭显示设备文件

    void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);

    功能:建立文件和用户空间的内存映射

    参数:
            addr:要映射的用户空间首地址
                    NULL:让内核选取空间,并将空间首地址返回
            length: 要映射的空间大小
            prot:对映射空间的读写执行权限

                    PROT_READ I PROT_WRITE

            flags:MAP_SHARED (共享映射区域)

            fd:要映射的文件

            offset:映射的偏移量
    返回值:
            成功:映射到的用户空间首地址
            失败:MAP_FAILED((void *)-1)

    基础IO——系统IO | 文件描述符fd | 重定向 釜底抽薪、返璞归真....带你了解IO的真正原理 阅读详情

    相关推荐

    常见Linux文件IO(标准IO)解析

    说明:标准IO实际上是系统IO的封装,这种封装体现如下图所示,fopen(函数将调用open()函数得到的文件描述符填入结构体FILE中,并为文件分配缓冲区,设置缓冲区类型,最后给用户返回指向FILE的指针fp,成为文件指针每当使用标准IO的写操作函数,试图将数据写入文件a.txt时,数据都会流过缓冲中区,然后再在适当的时刻冲洗(或刷新flush)到内核,最后才真正写入设备文件。

    2401_85815460的博客 1077

    解码Linux文件IO之标准IO

    标准IO基础:C语言标准库提供遵循POSIX标准的IO函数(如fopen、fread),通过FILE结构体管理文件,包含文件描述符、缓冲区指针等。程序启动时自动打开3个标准流(stdin/stdout/stderr)。主要函数包括:fopen打开文件(支持文本/二进制模式),fgets安全读取行,fread高效读取块数据,fputc写入字符等。二进制模式直接处理原始字节,文本模式会转换换行符(Windows)。注意缓冲区管理和错误检查,避免安全问题(如避免使用已废弃的gets)。

    愿能与同路的你交流互鉴~ 博客园 :https://www.cnblogs.com/YouEmbedded/ 1273

    LCD、LED、OLED、Mini LED、Micro LED、全阵列LED、QLED、QD-OLED、QNED、AMOLED是什么意思?

    LCD(液晶显示器,Liquid Crystal Display)定义:LCD 是一种利用液晶材料控制光线通过的显示技术,需依靠背光源(如冷阴极荧光灯 CCFL 或 LED)照亮液晶层以形成图像。技术原理:液晶分子在电场作用下改变排列,控制背光通过的强度和颜色。液晶本身不发光,需外部光源。特点:结构包括背光层、液晶层、彩色滤光片和偏光片。响应时间较慢,黑色表现因背光漏光而偏灰。LED(发光二极管显示,Light Emitting Diode)定义。

    中国最威武的城市!武功军威-武威,铁骨铮铮! 3427

    Linux文件操作

    本文系统介绍了C语言和Linux中的文件操作机制。从C语言的fopen、fwrite等库函数入手,详细解析了文件打开模式、缓冲区刷新策略等核心概念。然后深入到Linux系统调用层面,讲解了open、write、read等底层接口的实现原理,包括文件描述符的分配规则和重定向机制。特别分析了缓冲区的实现原理,阐明了用户级缓冲区(FILE结构体)和内核级缓冲区的区别与联系。最后通过模拟实现C语言缓冲区和分析Linux内核源代码,展示了文件操作从用户层到内核层的完整调用链。全文揭示了编程语言文件操作与操作系统接口的

    KEEP ON KEEPING ON 1503

    windows10系统上安装最新版mysql 8.0详细步骤

    windows10系统上安装最新版mysql 8.0详细步骤

    glei20的博客 6715

    猫耳语音下载(mediadown)

    西宾猫耳语音下载工具,能够帮助你下载猫耳音频节目。如果你是会员,它还能帮你下载会员节目。

    new_stranger的专栏 2492

    C语言标准IO与文件操作——基础读写实战

    C语言标准IO与文件操作摘要 本文系统介绍了C语言标准IO库的文件操作基础。主要内容包括: 标准IO概述 - 标准IO是C语言提供的跨平台文件操作接口,核心是FILE结构体指针,包含fopen/fclose/fread/fwrite等函数。系统自动提供stdin/stdout/stderr三个标准流。 文件打开 - 详细说明fopen的各种模式(r/w/a及带+的读写模式),强调必须检查返回值是否为NULL。 数据写入 - 演示fwrite写入二进制数据块和fprintf格式化文本写入,包括结构体数组的写入

    爱片闲串,爱钓鱼,爱中医,爱分享 218

    Visual Studio 2022 社区版安装指南:从下载到配置的完整流程

    本文详细介绍了Visual Studio 2022社区版的完整安装与配置流程,包括系统要求检查、官方下载步骤、工作负载选择、安装位置配置等关键环节。作为微软推出的免费集成开发环境,VS2022社区版支持多种编程语言,适合个人开发者和小型团队使用。文章还提供了常见问题解决和性能优化技巧,帮助用户高效完成开发环境搭建。

    weixin_28829339的博客 880

    C语言歌词解析项目

    C语言歌词解析项目 去发现同类优质开源项目:https://gitcode.com/ 项目简介 本项目是一个基于Linux操作系统的C语言歌词解析项目,适用于Linux Ubuntu开发环境。项目的主要功能包括读取、解析lrc格式的歌词文件,并创建链表以实现歌词的实时显示。 功能特点 文件读取与解析:能够读取lrc格式的歌词文件,并对其内容进行解析。 链表创建:使用双向链表存储解析后的歌词信息,...

    gitblog_06759的博客 868

    福建公共资源交易平台 portal-sign与响应Data解密逆向实录

    本文分析了福建公共资源交易电子公共服务平台的接口加密机制。通过抓包和代码分析,发现请求头中的portal-sign由MD5算法生成,包含固定秘钥和排序后的参数拼接。响应数据采用AES-256-CBC加密,需使用特定Key和IV解密。文章详细介绍了签名生成规则、参数处理流程及加密常量定位方法,为接口对接提供了技术参考。整个过程展示了如何通过逆向工程还原前端加密逻辑,最终实现脱离浏览器环境的纯协议调用。

    自成背后的博客 1157

    LLC谐振变换器软启动,不只是“慢启动”,还是“智能启动”

    LLC谐振变换器的软启动,不只是“慢慢来”,而是要在控制时序、限流、响应速度之间精妙权衡。而数字控制,特别是用查表法或混合信号法,为实现真正的“最佳轨迹”提供了可能。✨小Tips:如果你的系统成本敏感,选择查表法准没错;如果你的设计目标是超高速响应,那就上混合信号的高配方案!

    weixin_43199439的博客 691

    从基础到本质:文件 IO 操作全解析

    本文深入解析了文件IO操作的核心原理,从"文件"概念的广义理解到C语言文件接口的实际应用。主要内容包括:1)Linux"一切皆文件"的抽象设计;2)文件操作背后的系统调用过程;3)C语言文件读写的最佳实践;4)标准流(stderr/stdout)的设计智慧;5)文件打开模式的深度对比。通过实际代码示例,揭示了文件IO从用户层到系统层的完整执行链路,帮助开发者真正理解文件操作的本质。

    先做,然后做对,最后做得更好。学习就是为了自由呀,当你学会了怎么学习,想要学什么就学什么,需要什么就学什么,你就自由了。 939

    Oracle EBS 帐套(Ledger/SOB)如何定义会计主体、如何支撑多准则 / 多报告、组织与帐套的绑定关系、以及项目落地时的设计差异。下面从实现逻辑、核心要素、组织模型、多账簿、科目设计、项

    本文对比了Oracle EBS R12与SAP S/4HANA在帐套(Ledger)设计上的核心差异。Oracle采用4C架构(科目/币种/日历/准则),帐套作为独立会计主体,主辅账物理隔离;SAP则以公司代码为主体,通过平行分类账在同一凭证中实现多准则核算。关键差异体现在:Oracle强调边界隔离,适合差异大的集团;SAP注重统一视图,适合实时合并需求。实施时需注意:Oracle避免过度建账套,SAP需统筹科目与维度设计。两者分别体现了"盒子"与"滤镜"的设计哲学。

    金牌架构师 417

    Linux操作系统之文件IO

    文件的宏观理解:文件是在硬盘上存储的,对文件的所有操作,都是对外设的输入输出,简称IO即使磁盘上有空文件,但是他依然占用我们的磁盘空间,因为,这里只是说的内容的大小和占用空间,而,所以一个空文件依旧占用磁盘空间,所以我们所学的文件操作,对文件的操作,本质都是进程对文件的操作,C语言提供的库函数是在用户层,不能直接访问硬件,库函数是去调用系统调用接口去访问硬件的。

    Frank_refuel的博客 1155

    jre9下载 jdk9

    (Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

    温度PID控制PLC程序

    温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

    文件编程-标准IO

    保存数据,掉电数据不丢失,保存在硬盘(外存)linux中一切皆文件(硬盘、鼠标、键盘、显示器、普通文件....b c d - l s p七种文件类型块设备文件(硬盘)字符设备文件(鼠标、键盘、显示器、外设传感器...目录文件(文件夹)普通文件(链接文件(类似于快捷方式)套接字文件(网络通信)管道文件(进程间通信)1.Linux下的两种文件操作方式标准IOC标准库提供的对文件的操作接口(库函数)如printfscanf文件IOLinux。

    chen_ziy的博客 208

    lwip-2.0.3

    lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

    Linux:基础IO(18+19)+文件描述符

    struct file 表示被打开的文件, 对文件的管理就变成了对struct file链表的增删查改。文件打开 -- 内核创建struct file内容加载到文件缓冲区, 属性初始化到struct file系统初始化,创建一个文件描述符表:struct files_struct里面包含一个对象, struct file* fd_array[]指向不同的被打开的文件。文件描述符的本质就是数组下标。

    WG_17的博客 691

    android 蓝牙通讯demo

    android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

    基础IO理解

    基础IO的文字和图理解

    2301_79811170的博客 340

    #Linux中的GCC编程# 标准IO与系统IO

    标准IO,默认采用了缓冲机制,比如调用fopen函数,不仅打开一个文件,而且建立了一个缓冲区。 读写模式下将建立两个缓冲区),还创建了一个包含文件和缓冲区相关数据的数据结构。 #include &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;stdio.h&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;g

    Kshine2017的博客 1065

    Linux下C语言文件操作全解析:从open到close的完整实践

    在Linux系统编程中,文件IO是开发者必须掌握的核心技能。理解文件描述符的工作机制,是深入操作系统底层的基础。系统调用如open、read、write、close等,构成了文件操作的地基,控制着数据的读写与资源释放。通过实践文件复制程序,可以直观感受缓冲区大小对性能的影响,并学会处理EINTR、文件描述符泄漏等常见问题。本文从设计哲学到代码实现,系统梳理C语言在Linux下的文件操作,帮助开发者写出健壮的工程代码。

    weixin_29302047的博客 319

    快速掌握Linux(1)(Linux文件操作)(标准IO)

    C编程语言数据结构Linux应用软件编程1. 文件操作2. 多任务(进程、线程)3. 网络编程4. 数据库。

    2303_78364226的博客 162

    C文件操作与系统IO

    本文介绍了文件操作的系统调用和C标准库接口。主要内容包括:1. 文件在磁盘的存储方式及属性;2. C语言文件操作接口如fopen、fwrite、fread的使用方法;3. 系统级文件I/O操作如open、write、read的实现;4. 文件描述符的概念、分配规则及重定向原理;5. 缓冲区的基本概念。重点讲解了系统调用与库函数的关系,以及通过文件描述符实现I/O重定向的机制,体现了Linux"一切皆文件"的设计理念。

    2401_86525813的博客 602

    从零开始的敲代码生活--Linux应用软件(文件操作基础1)

    程序变量、数组、数据结构存放在内存;文件存储在外存(硬盘)。文件用于长期保存掉电不丢失的数据。Linux一切皆文件,硬件也通过文件接口给应用层操作。

    2601_96620724的博客 513

    文件编程--标准IO

    ggglinux中一切皆文件,对文件的操作步骤分为三步1.打开2.读写3.关闭标准IO库 ---- stdio中有对应的函数1.打开fopen2.读写一切皆文件的思想简化linux对文件的处理,可以使用统一的操作逻辑。

    imaol1的博客 227

    【Linux系统】基础IO(上)

    fopenfwrite磁盘作为计算机外设的一种,既是输入设备(读取数据)也是输出设备(写入数据)。所有对磁盘文件的操作(创建、读取、修改、删除)本质上都是通过操作系统提供的输入输出(IO)接口完成的。总结:狭义文件强调磁盘存储的永久性和硬件交互的IO本质,所有操作都围绕外设进行。1.2 文件的广义理解在Linux/Unix操作系统中,有一个重要的设计理念:"一切皆文件"。这意味着:••这种抽象极大简化了系统编程接口,开发者可以使用统一的文件操作API来访问各种资源。1.3 文件操作的分类认知。

    tomatop的博客 34

    理解 Linux 动态库加载:LD_LIBRARY_PATH

    flyfish

    二分掌柜的 349
    上一篇: 朝花夕拾 · 数据结构 | 哈希表篇
    下一篇: Linux多任务-进程篇
    剑指offer.
    博客等级 码龄3年 15粉丝 38原创
    评论
    成就一亿技术人!
    拼手气红包6.0元
    还能输入1000个字符
     
     条评论被折叠 查看
    添加红包

    请填写红包祝福语或标题

    个

    红包个数最小为10个

    元

    红包金额最低5元

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

    抵扣说明:

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

    余额充值