Home C 文件读写
Post
Cancel

C 文件读写

open() write() read()

open是linux下的底层系统调用函数,在linux下如果需要对设备进行明确的控制,那最好使用底层系统调用(open)

导包,引入依赖

1
#include <libc.h>

open()

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 * @params pathname 文件路径,可以为相对路径或绝对路径。如:"test.txt"
 * @params flags 文件打开方式,例如:
 *    "O_RDONLY" 以只读方式打开文件,该文件必须存在。
 *    "O_WRONLY" 以只写方式打开文件
 *    "O_RDWR" 以可读写方式打开文件.和O_RDONLY和O_WRONLY都不能同时使用
 *    "O_CREAT" 若欲打开的文件不存在则自动建立该文件.经常和上面的同时使用。
 *    "O_EXCL" 如果O_CREAT 也被设置, 此指令会去检查文件是否存在. 文件若不存在则建立该文件, 否则将导致打开文件错误. 此外, 若O_CREAT
 * @params mode 文件权限,只有在建立新文件时才会生效。
 * @return 成功  返回文件句柄 ,失败  返回-1
 */
int open(const char * pathname, int flags);
int open(const char * pathname, int flags, mode_t mode);

close()

1
2
3
4
5
/**
 * @params handle 文件句柄
 * @return 
 */
int close(int handle)

write()

1
2
3
4
5
6
7
/**
 * @params handle 为要获取文件指针的文件句柄
 * @params *buf 为要写入的内容
 * @params len 为要写入文件的长度
 * @return 返回实际写入文件内容的长度
 */
int write(int handle,void *buf,int len);

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <libc.h>

int main() {
    // 1.打开/创建
    int fd = open("file.txt", O_WRONLY | O_CREAT);
    if (-1 == fd) // 创建文件失败,则异常返回
    {
        printf("can't not open file\n");
        return -1;
    }

    char buffer[1024] = "*send!";
    // 2.写入
    write(fd, buffer, strlen(buffer));

    // 3.关闭
    close(fd);
    return 0;
}

read()

1
2
3
4
5
6
7
/**
 * @params stream 为要读取的文件的文件句柄
 * @params *buf 读取到的缓冲区
 * @params len 读取文件长度
 * @return 实际读取到的字节数
 */
 int read(int handle,void *buf,int len);

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <libc.h>

int main() {
    // 1. 打开/创建
    int fd = open("file.txt", O_RDONLY | O_CREAT);  //  |O_TRUNC
    if (-1 == fd) // 创建文件失败,则异常返回
    {
        return -1;
    }

    // 2. 读取
    char buffer[1024];
    size_t flag = read(fd, buffer, strlen(buffer));
    printf("read str is :len: %zu, content: %s\n", flag, buffer);

   // 3. 关闭
    close(fd);
    return 0;
}

fopen() fwrite() fread()

linux下的fopen是open的封装函数,fopen最终还是要调用底层的系统调用open。fopen是c/c++下的标准I/O库函数,带输入/输出缓冲。

这三个函数都在stdio.h里,所以想要使用需要先进行include

1
#include <stdio.h>

fopen()

在C语言中fopen()函数用于打开指定路径的文件,获取指向该文件的指针。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
 * @params path 文件路径,可以为相对路径或绝对路径。如:"test.txt"或"F:\Visual Stdio 2012\test.txt"
 * @params mode 文件打开方式,例如:
 *    "r" 以只读方式打开文件,该文件必须存在。
 *    "w" 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
 *    "w+" 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
 *    "a" 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)
 *    "a+" 以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。(原来的EOF符不保留)
 *    "wb" 只写打开或新建一个二进制文件,只允许写数据。
 *    "wb+" 读写打开或建立一个二进制文件,允许读和写。
 *    "ab" 追加打开一个二进制文件,并在文件末尾写数据。
 *    "ab+"读写打开一个二进制文件,允许读,或在文件末追加数据。   
 * @return 文件顺利打开后,指向该流的文件指针就会被返回,会指向文件首或者文件末位,跟随文件的读写往后移动。如果文件打开失败则返回NULL,并把错误代码存在errno中。
 */
FILE * fopen(const char * path,const char * mode);

fclose()

写完数据后要调用fclose()关闭流,不关闭流的情况下,每次读或写数据后,文件指针都会指向下一个待写或者读数据位置的指针。如果需要读写,需要在一个操作完成后close后,再重新打开文件。

fwrite()

在C语言中fwrite()函数常用语将一块内存区域中的数据写入到本地文本。

1
2
3
4
5
6
7
8
/**
 * @params buffer 指向数据块的指针
 * @params size 每个数据的大小,单位为Byte(例如:sizeof(int)就是4)
 * @params count 数据个数
 * @params stream 文件指针
 * @return 写入的count
 */
size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);

返回值会根据写入的形式而不同。

  • 推荐 fwrite(buf,sizeof(buf),1,fp);,成功写入返回值为1(即count)

  • fwrite(buf,1,sizeof(buf),fp); 成功写入则返回实际写入的数据个数(单位为Byte),即int就为4

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include "string.h"

int main() {
    int age = 18;
    FILE *fp = fopen("file.txt", "w");

    if (fp == NULL)
        printf("can't not open file");

    // 写入int
    fwrite(&age, sizeof(int), 1, fp);

    char* name = "jiangker";
    // 写入 char[]
    fwrite(name, sizeof(char), strlen(name), fp);

    fclose(fp);
    return 0;
}

打开文本文件可以看到,最前面的int乱码

当然还可以使用fprintf()来输出到文件

1
2
3
4
5
6
7
/**
 * @params stream 文件指针
 * @params buffer 指向数据块的指针
 * @params ... 格式化匹配
 * @return 写入的count
 */
int	 fprintf(FILE * stream, const char * buffer, ...) 

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include "string.h"

int main() {
    int age = 18;
    char *name = "jiangker";

    FILE *fp = fopen("file.txt", "w");
    if (fp == NULL)
        printf("can't not open file");

    // 类似于输出到控制台的函数。
    fprintf(fp,"%d%s",age,name);

    fclose(fp);
    return 0;
}

这里直接拼接到char *中进行写入,所以最终显示看起来正常。

fread()

从一个文件流中读取数据

1
2
3
4
5
6
7
8
/**
 * @params buffer 指向数据块的指针
 * @params size 每个数据的大小,单位为Byte(例如:sizeof(int)就是4)
 * @params count 数据个数
 * @params stream 文件指针
 * @return 读取到count
 */
size_t fread(void *buffer, size_t size, size_t count, FILE *stream);

返回值随着调用格式的不同而不同:

  • 推荐 fread(buf,sizeof(buf),1,fp); 读取成功时:当读取的数据量正好是sizeof(buf)个Byte时,返回值为1(即count),否则返回值为0(读取数据量小于sizeof(buf))

  • fread(buf,1,sizeof(buf),fp); 读取成功返回值为实际读回的数据个数(单位为Byte)

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include "string.h"

int main() {

    FILE *fp = fopen("file.txt", "r");`

    if (fp == NULL)
        printf("can't not open file");

    fread(&read, sizeof(int), 1, fp);

    // 对于第一处直接使用int来写入的地方,这个可以正确读取会原来的值。而对于第二种char *方式写入则不能。
    printf("read count %d", read);

    fclose(fp);
    return 0;
}

参考文档

This post is licensed under CC BY 4.0 by the author.