Linux下的文件操作----高级文件操作

Linux下的文件操作----高级文件操作

基于文件指针的文件操作,有缓冲区,是高级文件的操作,属于底层文件系统

一、fopen();文件打开、创建函数

FILE *fopen(const char *__restrict__ __filename, const char *__restrict__ __modes);
  • 函数声明: FILE *fopen(const char *restrict __filename, const char *restrict __modes);
  • 函数功能: 根据 __modes设定的读写方式,创建\打开文件
  • 参数: 参数1: 文件路径名(可以是char*变量); 参数2: 文件读写方式;
  • 返回值: 打开成功返回文件指针 打开失败返回NULL

modes的参数列表

对于打开文件所选择的操作方式来说,一经选择将不可改变,除非关闭文件后重新打开。
文本文件(ASCII)
模式功能描述文件读写位置备注
“r”打开只读文件,文件必须存在,如果不存在则会报错。从头开始读
“w”以只写的创建新文件,如果该文件存在,则将文件里的内容覆盖(先清空再写)。从头开始写
“a”以只写的方式打开文件,将要写的内容追加到该文件原有的数据后面,如果该文件不存在,则创建该文件。从末尾继续写
“r+”以可读可写的方式打开文件,如果文件不存在则会报错。在写数据时会将原数据覆盖*****(先清空再写)。从头开始读或写,如果打开文件后有多个读写操作接续上一次的读写位置。注意:以这种方式打开文件,读文件的不会清空文件。
“w+”以可读可写的方式打开文件,如果文件不存在,则创建该文件,如果文件存在,写入数据时会将原内容覆盖*****(先清空再读,先清空再写)。从头开始读或写,如果打开文件后有多个读写操作,则接续上一次的读写位置。注意:以这种方式打开文件,读文件会先清空文件在执行度读操作,读取的数据量为0。
“a+”以可读可写的方式打开文件,如果文件不存在,则创建该文件,如果文件存在,写入数据时会追加在原数据后面。从头开始读或从结尾接续写,如果打开文件后有多个读写操作,则接续上一次的读写位置。

注意:在读取字符数据的时候,无论数据有没有读完当读到 ‘\0’ 时,读结束。

二进制文件(Binary)
模式功能描述文件读写位置备注
“rb”打开只读文件,文件必须存在,如果不存在则会报错。从头开始读
“wb”以只写的创建新文件,如果该文件存在,则将文件里的内容覆盖(先清空再写)。从头开始写
“ab”以只写的方式打开文件,将要写的内容追加到该文件原有的数据后面,如果该文件不存在,则创建该文件。从末尾继续写
“rb+”以可读可写的方式打开文件,如果文件不存在则会报错。在写数据时会将原数据覆盖*****(先清空再写)。从头开始读或写,如果打开文件后有多个读写操作接续上一次的读写位置。*注意:以这种方式打开文件,读文件的不会清空文件。
“wb+”以可读可写的方式打开文件,如果文件不存在,则创建该文件,如果文件存在,写入数据时会将原内容覆盖*****(先清空再读,先清空再写)。从头开始读或写,如果打开文件后有多个读写操作,则接续上一次的读写位置。*注意:以这种方式打开文件,读文件会先清空文件在执行度读操作,读取的数据量为0。
“ab+”以可读可写的方式打开文件,如果文件不存在,则创建该文件,如果文件存在,写入数据时会追加在原数据后面。从头开始读或写,如果打开文件后有多个读写操作,则接续上一次的读写位置。
注意:在读取字符数据的时候,无论数据有没有读完当读到 ‘\0’ 时,读结束。

字符文件和二进制文件在我们自己使用的时候感觉不到区别,两者的用法相同。她俩的区别就是存储区别,例如:一个int 数字 147483647,如果按照字符存储,需要占用9个字节,如果按二进制存储就是int 本身的4个字节。 其实我感觉区别不大,因为我用文本文件的打开方式打开文件,存入int类型的数据它也是4个字节,也就是说你存什么类型的数据,它就占有那个类型的字节数。

二、fclose();文件关闭函数

  • 函数声明: int fclose(FILE * stream);
  • 函数功能: 关闭stream指向的文件,并将缓冲区内容写入文件
  • 参数: 要关闭的文件的文件指针;
  • 返回值: 关闭成功返回 0 ,关闭失败返回EOF (-1)

三、fwrite(); 文件写函数

  • 函数声明: size_t fwrite(const void *restrict __ptr, size_t __size, size_t __n, FILE *restrict __s);
  • 函数功能: 将__ptr指向的地址空间的的数据 ,以每次__size 个字节,写入__n 个 到文件指针 __s 指向的文件里
  • 参数: 参数1: 指向要读取的数据的地址空间的指针; 参数2: 用户自定的元素的字节大小; 参数3: 一次写入几个元素; 参数4: 文件指针;
  • 返回值:写入文件的字节数(size_t 就是long int)

四、fread(); 文件读函数

函数声明: size_t fread(void *restrict __ptr, size_t __size, size_t __n, FILE *restrict __stream)
函数功能: 从__stream指向的文件里读取__n个 __size字节大小的元素到__ptr指向的地址空间里;
参数: 参数1: 从文件中读取的内容要存放的地址空间,是一个指针; 参数2: 用户自定的元素的字节大小; 参数3: 一次读取几个元素; 参数4: 文件指针
返回值:写入文件的字节数(size_t 就是long int)

;

五、fseek();文件读写位置偏移函数

函数声明: int fseek(FILE *__stream, long __offest int __whence)
函数功能: 从当前读写位置偏移offest 字节,其中offest 可以为负数,负数就是向前偏移,0 就是不偏移,正数就是向后偏移。
参数: 参数1: 当前文件的文件指针 参数2:偏移量(可以为负数) 参数2: 偏移方式(三种方式:SEEK_SET、SEEK_CUR、SEEK_END)
偏移方式功能描述
SEEK_SET距文件开头偏移offest个字节
SEEK_CUR从当前偏移offest个字节
SEEK_END距文件末尾偏移offest个字节
返回值: 函数调用成功时则返回 0,若有错误则返回-1

六、rewind(); 文件读写位置重置函数

函数声明: void rewind(FILE *__stream);
函数功能: 将文件的读写位置移至文件开头
参数: 当文件的文件指针
返回值: 无

七、perror(); 错误提示函数

函数声明: void perror(const char *s);
函数功能: 将上一个函数发生错误的原因输出,先输出字符串s,然后再在字符串s后输出错误原因,字符串s和上一个发生错误的函数,没有一点关系你把它设置成 “张三” 都行。
例1:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EfaPLE0c-1639191213027)(C:\Users\纵横四海\AppData\Roaming\Typora\typora-user-images\image-20211201191932491.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9kU6pgGr-1639191213029)(C:\Users\纵横四海\AppData\Roaming\Typora\typora-user-images\image-20211201192010407.png)]

例2:

在这里插入图片描述

参数: 用户自定的字符串(char*)
返回值: 无

八、exit(); 终结当前进程函数

函数声明: void exit(int status);
函数功能: 正常结束当前进程的执行,而进程所有的缓冲区里的数据会自动写回并关闭未关闭的文件。
参数: 参数:0或非0,当值为0时,表示程序正常退出; 非0值时,表示程序异常退出。
返回值: 无

PS: 我们也可以使用return结束当前函数或程序 return 0(正常结束)、return -1(异常结束) ,会将缓冲区内容写入文件然后结束程序

对以上八个函数进行运用,例程如下:
#include<stdio.h>
#include<string.h>


int main(void)
{
    FILE *fp = NULL;

    char str[50] = {0};
    char buf[50] = {0};

/*
    fopen
    函数声明: FILE *fopen(const char *__restrict__ __filename, const char *__restrict__ __modes);
    函数功能: 根据 __modes设定的读写方式,创建\打开文件
    参数: 参数1: 文件路径名(可以是char*变量); 参数2: 文件读写方式;
    返回值: 打开成功返回文件指针   打开失败返回NULL
*/

    if((fp = fopen("file1.txt","w+")) == NULL) // 以读写的方式打开或创建文件file1.txt。
    {
        perror("fopen"); // 打开失败给出错误信息
        if(fclose(fp) == EOF)	//关闭文件
        {
            perror("fclose"); //文件关闭失败给出错误信息
            exit(0); // 关闭文件失败,退出进程
        }
    }

    printf("请输入:\n");
    gets(str); // 从命令行界面获取字符串

/*
    fwrite
    函数声明: size_t fwrite(const void *__restrict__ __ptr, size_t __size, size_t __n, FILE *__restrict__ __s);
    函数功能: 将__ptr指向的地址空间的的数据 ,以每次__size 个字节,写入__n 个 到文件指针 __s 指向的文件里
    参数: 参数1: 指向要读取的数据的地址空间的指针;  参数2: 用户自定的元素的字节大小;  参数3: 一次写入几个元素;  参数4: 文件指针;
    返回值:写入文件的字节数(size_t 就是long int)  
*/
    int num = fwrite(str,strlen(str),1,fp);

    printf("Write %d byte\n",num);


/*
    rewind
    函数声明: void rewind(FILE *__stream);
    函数功能: 用来把文件流的读写位置移至文件开头。
    参数: 参数: 文件指针;
    返回值: 无
*/
    rewind(fp); // 将文件读写位置置于文件开头
// fseek(fp,0,SEEK_SET); // 距文件开头偏移0个字节,即文件开头

/*
    fread
    函数声明: size_t fread(void *__restrict__ __ptr, size_t __size, size_t __n, FILE *__restrict__ __stream)
    函数功能: 
    参数: 参数1: 从文件中读取的内容要存放的地址空间,是一个指针;  参数2: 用户自定的元素的字节大小;  参数3: 一次读取几个元素; 参数4: 文件指针
    返回值:写入文件的字节数(size_t 就是long int) 
*/
    int n = fread(buf,strlen(str),1,fp);

    printf("Read %d  byte\n",n);

    printf("读出的结果:%s\n",buf);


    fclose(fp);
}

九、fprintf(); 格式化输出内容到文件

函数声明: int fprintf(FILE * stream, const char * format,…);
函数功能: 根据参数format字符串来转换并格式化数据,然后将结果输出到参数stream指定的文件中,直到出现字符串结束符( ‘\0’ )为止. 其实就是把不同类型的数据,转换为字符串输出到指定字符串。
参数: stream:文件指针;format : 字符串的格式 ; 其他参数:和字符串format里的格式符相对应类型的变量
返回值: 成功把内容输出到文件则返回实际输出的字符数,失败则返回-1.
例:

在这里插入图片描述

十、fscanf(); 从文件中格式化读取内容

函数声明: int fscanf(FILE * stream ,const char *format,…);
函数功能: 从stream指向的文件流中读取字符串,再根据format字符串格式来转换和格式化数据,将对应的数据写入到与格式符对应类型的变量。
参数: stream:文件流指针; format:字符串读取的格式; 其他参数:将字符串里相应的字符转换为格式符对应的变量类型,并赋值给对应的变量
返回值: 成功则返回参数数目,失败则返回-1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8bTUNpaX-1639191213034)(C:\Users\纵横四海\AppData\Roaming\Typora\typora-user-images\image-20211201235105777.png)]

注意:读取的字符串和要转换的字符串 字符的位置、数量、格式符的位置要一模一样,例如从文件里读取 “ PI = 3.14159 ” , fscanf里的字符串必须是“ PI = %lf ”,这样才能把3.14159 准确无误的转换成 double类型的数据。

十一、printf();

函数声明: int printf(const char * format,…);
函数功能: 根据参数format字符串来转换并格式化数据,并将结果输出到标准输出设备,遇到 ‘ \0 ’ 停止
参数: %(flags) (width) (.digit) type

括号内是可选的参数,其中%和type是固定搭配

flags:

’ - ’ : 当flag是这个’ - '时(不包括单引号),表示该type对应的变量输出时左对齐,不加该符号默认右对齐

’ + ’ : 我们知道当我们打印一个负数时,会自动在前面加一个符号,正数默认不加,加上这个符号正数也默认加正号

’ # ’ :此符号会根据其后转换字符的不同而有不同含义。当在类型为o 之前(如%#o),则会在打印八进制数值前多印一个 o。而在类型为 x 之前(%#x)则会在打印十六进制数前多印’0x’,在型态为 e、E、f、g 或 G 之前则会强迫数值打印小数点。在类型为 g 或 G 之前时则同时保留小数点及小数位数末尾的零。

’ 0 ’ : 字符零当指定输出宽度时,想左空位补零

width: 指定type对应变量输出字符时占有的宽度

digit:

​ 1. 如果是数字的话 : 表示保留几个数据位,对整数不起作用,对浮点数就是保留digit位小数,对于字符串就是输出digit个字符。如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A2ViXDmd-1639191213035)(C:\Users\纵横四海\AppData\Roaming\Typora\typora-user-images\image-20211202163416069.png)]

​ 2.在%g 格式下代表保留digit位有效数字(四舍五入,小数点前的数字位也算上)

​ 3.如果digit 不是数字,而是 * 则可以指定一个可变数字,控制输出的数据位,例如:可以通过变量控制每次打印的字符数,来打印直角三角形,如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZxcUGckR-1639191213036)(C:\Users\纵横四海\AppData\Roaming\Typora\typora-user-images\image-20211202165500581.png)]

​ ’ * ’ 也可以这样使用,如下所示:

printf("weight = %*.*f\n",width,precision,weight);
type的可选参数如下表所示:

在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XKNRRF65-1639191213037)(C:\Users\纵横四海\AppData\Roaming\Typora\typora-user-images\image-20211202154322970.png)]

返回值: int类型 ,返回输出的字符数

十二、scanf();

函数声明: int scanf(const char * format,…);
函数功能: 根据 fromat字符串来转换并格式化数据
参数: % ( * ) ( size ) ( l ) ( h ) type , 括号内为可选参数,其中%和type这两个符号是固定搭配
  1. ​ ***** :代表该对应的参数数据忽略不保存 , 示例如下如所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6rAnPzuF-1639191213038)(C:\Users\纵横四海\AppData\Roaming\Typora\typora-user-images\image-20211202173240502.png)]

  1. ​ size :表示允许输入的数据长度
  2. ​ l : 输入的数据数值以 long int 或 double 型保存
  3. ​ h :输入的数据数值以 short int 型保存
  4. type : type的可选形式及功能 如下表所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dd93D4df-1639191213039)(C:\Users\纵横四海\AppData\Roaming\Typora\typora-user-images\image-20211202191635430.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AxAt1iG8-1639191213040)(C:\Users\纵横四海\AppData\Roaming\Typora\typora-user-images\image-20211202190330529.png)]

​ 图1 %i 演示图

返回值: 成功则返回参数数目,失败则返回-1

十三、sprintf();

函数声明: int sprintf( char *str,const char * format,…);
函数功能: 将格式化字符串写入到 str 指向的地址空间里
参数: str: 字符串指针,指向一个地址空间,用于存储格式化的字符串,format: 格式化字符串
返回值: 返回写入str中的字符个数

十四、sscanf();

函数声明: int sscanf (const char *str,const char * format,…);
函数功能: 将str字符串按照 format的格式进行格式化,将与格式符对应的字符转换为相应类型变量,并赋值给对应类型的变量
参数: str: 要转换的字符串, format:要转换的字符串格式
返回值: 成功则返回参数数目,失败则返回-1

十五、fflush、

函数声明: int fflush(FILE* stream);
函数功能: 刷新缓冲区,将缓冲区里的数据写入文件
参数: stream:文件指针
返回值: 成功返回 0,失败返回 EOF

十六、fgetc()

函数声明: int fgetc(FILE * stream);
函数功能: 从文件指针stream 所指的文件中读取一个字符。若读到文件尾而无数据时便返回 EOF。
参数: stream:文件流指针
返回值: 返回读取到的字符,若返回 EOF 则表示到了文件尾

这里存疑:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9xQQJQcU-1639191213041)(C:\Users\纵横四海\AppData\Roaming\Typora\typora-user-images\image-20211211004706181.png)]

十七、fputc()

函数声明: int fputc(int c,FILE * stream);
函数功能: fputc 会将参数 c 转为 unsigned char 后写入参数 stream 指定的文件中
参数: c:要写入的字符 , strean : 文件流指针
返回值: 写入成功返回写入的字符,即参数 c。若写入失败返回 EOF

十八、fgets()

函数声明: char * fgets(char * s,int size,FILE * stream);
函数功能: fgets()用来从参数 stream 所指的文件内读入字符并存到参数 s 所指的内存空间,直到出现换行字符、读到文件尾或是已读了 size-1个字符为止, 最后会加上 NULL 作为字符串结束
参数: s: 要存放字符串的地址 , size: 要读取size个字符串,其中最后一个字符是 ‘\0’ ,也就是实际读取的字符数为size-1个 ,stream:文件流指针
返回值: 若读取成功则返回 s 指针,返回 NULL 则表示有错误发生。

十九、fputs()

函数声明: int fputs(const char * s,FILE * stream);
函数功能: fputs() 用来将参数 s 所指的字符串写入到参数 stream 所指的文件内 ,遇到 '\0’停止输出 ,遇到换行不影响
参数: s : 字符串存取的地址 , stream: 文件流指针
返回值: 若写入成功则返回写出的字符个数,写入失败返回 EOF

二十、getc()

函数声明: int getc(FILE * stream);
函数功能: getc()用来从参数 stream 所指的文件中读取一个字符。若读到文件尾而无数据时便返回 EOF。虽然 getc()与 fgetc()作用相同,
				但 getc()为宏定义,非真正的函数调用。
参数: stream:文件流指针
返回值: 成功则返回输出成功的字符的ASSIC码值,即参数 c。失败则返回 EOF

二十一、putc()

函数声明: int putc(int c,FILE * stream);
函数功能: putc()会将参数 c 转为 unsigned char 后写入参数 stream 指定的文件中。虽然 putc()与 fputc()作用相同,但 putc()为宏定义,非真正 的函数调用
参数: c : 字符的ASSIC码值, stream : 文件流指针
返回值: 成功则返回输出成功的字符的ASSIC码值,即参数 c。失败则返回 EOF

二十一、gets()

函数声明: char * gets(char *s);
函数功能: gets()用来从标准设备读入字符并存到参数 s 所指的内存空间,直到出现换行字符或读到文件尾为止,最后加上 NULL 作为字符串结束。
参数: s : 字符串指针
返回值: 成功则返回 s 指针,返回 NULL 则表示有错误发生

注意:gets()无法知道字符串 s 的大小,必须遇到换行字符或文件尾才会结束输入,因此容易造成缓冲区溢出的安全性问题。建议使用fgets()取代。

二十二、puts()

函数声明: int puts(const char *s);
函数功能: 将字符串 s 输出,遇到 ‘\0’ 文件尾结束
参数: s : 字符串指针
返回值: 成功则返回写出的字符个数,写入失败返回 EOF

二十三、getchar()

函数声明: int getchar(void);
函数功能: getchar() 用来从标准输入设备(键盘)中读取一个字符。然后将该字符从unsigned char 转换成 int 后返回。
参数: 无
返回值: 成功则字符的 ASSIC 值,返回 EOF 则表示有错误发生

二十四、putchar()

函数声明: int putchar (int c);
函数功能: putchar() 用来将ASSIC码值为 c 字符写到标准输出设备
参数: c : 字符的ASSIC码值
返回值: 成功则返回输出成功的字符的ASSIC码值,即参数 c。失败则返回 EOF

putchar (int c); 是 putc(c,stdout)宏定义

fgetc, fputc, getc, putc, getchar, putchar

fgets, fputs, gets, puts

函数声明: int getchar(void);

函数功能: getchar() 用来从标准输入设备(键盘)中读取一个字符。然后将该字符从unsigned char 转换成 int 后返回。
参数: 无
返回值: 成功则字符的 ASSIC 值,返回 EOF 则表示有错误发生

二十四、putchar()

函数声明: int putchar (int c);
函数功能: putchar() 用来将ASSIC码值为 c 字符写到标准输出设备
参数: c : 字符的ASSIC码值
返回值: 成功则返回输出成功的字符的ASSIC码值,即参数 c。失败则返回 EOF

putchar (int c); 是 putc(c,stdout)宏定义

fgetc, fputc, getc, putc, getchar, putchar

fgets, fputs, gets, puts

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
//1.创建文件file1,写入字符串“abcdefghijklmn”; //2.创建文件file2,写入字符串“ABCDEFGHIJKLMN”; //3.读取file1中的内容,写入file2,使file2中的字符串内容为“abcdefghijklmn ABCDEFGHIJKLMN” 创建新文件,该文件具有用户读写权限。 //2.采用dup/dup2/fcntl复制一个新的文件描述符,通过新文件描述符向文件写入“class_name”字符串; //3.通过原有的文件描述符读取文件中的内容,并且打印显示; 1.输入文件名称,能够判断文件类型,判断实际用户对该文件具有哪些存取权限; ?2.要求打印出文件类型信息,inode节点编号,链接数目,用户id,组id,文件大小信息; ?3.修改文件的权限为当前用户读写,组内用户读写,组外用户无权限 新建文件,设置文件权限屏蔽字为0; 2.建立该文件的硬链接文件,打印硬链接文件的inode节点号和文件大小; ? 3.建立该文件的软链接文件,打印软链接文件的inode节点号和文件大小;打印软链接文件中的内容; 4.打印源文件的inode节点号,文件大小和链接数目; ? 5.调用unlink对源文件进行操作,打印源文件链接数目; .新建/home/user目录; 2.把当前工作路径移至/home/user目录; 3.打印当前工作路径; ?编写程序完成以下功能: ?1.递归遍历/home目录,打印出所有文件和子目录名称及节点号。 ?2.判断文件类型,如果是子目录,继续进行递归遍历,直到遍历完所有子目录为止

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值