Linux系统编程笔记--I/O操作

1--I/O分类

sysio:称为系统调用IO(文件IO);

stdio:称为标准IO(标准IO基于系统调用IO来实现,其移植性好,一般优先调用)

2--fopen()

通过 man 手册来查看 fopen 的使用;

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

int main(){
	FILE *fp;
	fp = fopen("tmp", "r"); // read not create
	if(fp == NULL){
		// fprintf(stderr, "fopen() failed! errno = %d\n", errno);
		perror("fopen()");
		// fprintf(stderr, "fopen():%s\n", strerror(errno));
		exit(1);
	}
	puts("OK!");
    fclose(fp);
	exit(0);
}
vim fopen.c
make fopen
./fopen

查看单个线程能够打开的最大文件个数:ulimit -a(结果为 1024 个)

3--fclose()

fclose 用于关闭一个流,可通过 man 手册查看其用法;

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

int main(){
	FILE *fp;
	fp = fopen("tmp", "r"); // read not create
	if(fp == NULL){
		// fprintf(stderr, "fopen() failed! errno = %d\n", errno);
		perror("fopen()");
		// fprintf(stderr, "fopen():%s\n", strerror(errno));
		exit(1);
	}
	puts("OK!");
    fclose(fp);
	exit(0);
}

4--文件权限

文件权限: 0666 & ~umask,其中 umask 为 0002;

可通过 ll 查看文件的访问权限; 

5--fgetc()和fputc()

        fgetc() 从指定流获取一个字符,fputc() 将字符输出到指定流中,可通过 man 手册查看 fgetc() 和 fputc() 的用法;

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

int main(int argc, char *argv[]){
    if(argc < 3){
        fprintf(stderr, "Usage: %s <src_file> <dest_file>\n", argv[0]);
        exit(1);
    }

	FILE* fps, *fpd;
    fps = fopen(argv[1], "r");
    if(fps == NULL){
        fclose(fps);
        perror("fopen()");
        exit(1);
    }

    fpd = fopen(argv[2], "w");
    if(fpd == NULL){
        perror("fopen()");
        exit(1);
    }

    while(1){
        int ch = fgetc(fps); // 从fps读取一个字符
        if(ch == EOF) break;
        fputc(ch, fpd); // 将读取的字符写入fpd
    }

    fclose(fpd);
    fclose(fps);
	exit(0);
}

6--fgets()和fputs()

        fgets() 从指定流获取字符串,fputs() 将字符串输出到指定流中,可通过 man 手册查看 fgets() 和 fputs() 的用法;

// 用法
char *fgets(char *s, int size, FILE *stream);
int fputs(const char *s, FILE *stream);

// 伪代码
#define SIZE 5
char buf[SIZE];
fgets(buf, SIZE, stream);

// 假设 stream 的内容是 abcdef,读取 SIZE - 1 个字节,因为第 SIZE 个字节存取'\0'
// 则 fgets() 第一次读取的内容是: a b c d '\0',下一次从 e 开始读取

// 假设 stream 的内容是 ab
// 则 fgets() 可以一次读完,读取的内容为 a b '\n' '\0'

// 假设 stream 的内容是 abcd
// 则 fgets() 需要两次读完所有内容,第一次读取:a b c d '\0'
// 第二次读取: '\n' '\0' ...

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

#define SIZE 1024

int main(int argc, char *argv[]){
    if(argc < 3){
        fprintf(stderr, "Usage: %s <src_file> <dest_file>\n", argv[0]);
        exit(1);
    }

	FILE* fps, *fpd;
    fps = fopen(argv[1], "r");
    if(fps == NULL){
        fclose(fps);
        perror("fopen()");
        exit(1);
    }

    fpd = fopen(argv[2], "w");
    if(fpd == NULL){
        perror("fopen()");
        exit(1);
    }

    char buf[SIZE];
    while(fgets(buf, SIZE, fps)){ // 从 fps 中读取 SIZE-1 个字节,存放在buf中
        fputs(buf, fpd); // 将 buf 的内容写入 fpd 中
    }

    fclose(fpd);
    fclose(fps);
	exit(0);
}

7--fread()和fwrite()

fread() 和 fwrite() 用于从指定流读取和写入数据,可通过 man 手册查看其用法;

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
// 从 stream 中读取 nmemb 个对象,每个对象的大小为 size 字节,将读取的内容放到 ptr 中;
// fread() 一般是按单个字节来读取,即 size 的参数为 1

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
// ​​​​​​​On success, fread() and fwrite() return the number of items read or written.
// 即返回写入了或者读取了多少个数据
#include <stdio.h>
#include <stdlib.h>

#define SIZE 1024

int main(int argc, char *argv[]){
    if(argc < 3){
        fprintf(stderr, "Usage: %s <src_file> <dest_file>\n", argv[0]);
        exit(1);
    }

	FILE* fps, *fpd;
    fps = fopen(argv[1], "r");
    if(fps == NULL){
        fclose(fps);
        perror("fopen()");
        exit(1);
    }

    fpd = fopen(argv[2], "w");
    if(fpd == NULL){
        perror("fopen()");
        exit(1);
    }

    char buf[SIZE];
    int n;
    // 从 fps 中每次读取 SIZE 个字节,将其存放在buf中
    // 返回结果是:实际上读取的字节数,即 n 
    // 当读取的字节数 n > 0 时,继续读取
    while((n = fread(buf, 1, SIZE, fps)) > 0){
        // 读到 n 个对象,写入 n 个对象,因为fps中实际的字节数不一定是 SIZE 的整数倍
        // 最后一次读取,读到的字节数可能会小于 SIZE
        fwrite(buf, 1, n, fpd); // 从 buf 中将 n 个字节写入 fpd
    }

    fclose(fpd);
    fclose(fps);
	exit(0);
}

8--

猜你喜欢

转载自blog.csdn.net/weixin_43863869/article/details/132571726