嵌入式Linux☞文件编程
粗略的介绍Linux中有关文件系统的编程,包含了许多小栗子和源代码,为日后复习使用。
写在开头,文章仅用于日常学习笔记记录,不具备知识查阅质量。
文件编程:一组相关数据的有序集合。
文件名:这个集合的名字。
文件编程中 Linux 提供了两种函数:
标准IO库(库函数)
例如:printf(“hello\n”);
文件IO(系统调用)
例如:write(1,“word\n”,6);其中6 = 四个字符+一个换行符+一个 ‘\0’
Linux中文件类型:七大类型bcd lsp f
b:块设备文件:硬盘
c:字符设备文件:键盘屏幕鼠标
d:目录文件:eg/home/linux
f:常规文件:.c .bmp
l:链接文件:类似Windows下的快捷方式文件
p:管道文件:用于进程间的通信
s:套接字文件:用于进程间的通信
系统调用是进入内核的唯一路径。
Linux设计思想:
everything is file !
一切皆文件
perror打印系统错位信息
1,库函数标准IO操作文件:丹尼斯·里奇
1,缓存:减少系统调用次数,进而提高效率
2,流
库函数操作文件大致包括:
1,打开 fopen
2,读写 fgetc fputc fgets fputs,fwrite,fread
3,关闭 fclose
fopen
FILE *fopen(const char *pathname ,const char *mode);
@pathname 文件名 字符串形式
@mode 打开文件的方式
"r" 打开文件 做读操作
流定位在文件开头 ps:文件必须存在
"r+"读写 条件是文件存在
"w" 只写
文件存在 截断成0长度
文件不存在,创建文件
"w"+读写
"a" 文件存在时,在末尾写(追加)
文件不存在,创建文件
"a+"读 和 追加
读时,流定位在文件开始
追加,流定位在文件末尾
返回值:
成功: FILE*的指针
失败:NULL并且errno被设置,表明错误原因
其他函数:
fgetc/fputc 按字符读取写入
fgets/fputs 按字符串读取写入(按行读写)遇到'\n'停止
fread/fwrite 按对象读取写入
fgetc
int fgetc(FILE *stream)
功能:
从文件中(FILE *文件指针 流指针)读取一个字符
参数:
@stream 表示读取的文件
返回值:
成功:返回读取字符的ASCII码,int返回值
失败:返回EOF
1,表示到达文件末尾
2,表示出错
ps:如何判断读取字符是到达文件末尾还是出错???
fputc:
int fputc(int c,FILE *stream)
功能:将字符c写到stream对应的文件中
参数:输出的字符c,流指针
成功:返回被写入值的ASCII
失败:返回EOF
fclose(FILE *stream)
功能:断开流 关闭文件对于对的流指针
//打开文件
#include<stdio.h>
int main(int argc, const char *argv[])
{
FILE *fp = fopen("./hello.c","r");
if(fp==NULL)
{
// printf("open fail");
perror("open fail");
return -1;
}
return 0;
}
//实现touch功能:
//touch filename#include<stdio.h>
int main(int argc, const char *argv[])
{
if(argc !=2)
{
printf("usage: %s <filename>\n",argv[0]);
return -1;
}
FILE *fp = fopen(argv[1],"w");
if(fp==NULL)
{
// printf("open fail");
perror("open fail");
return -1;
}
return 0;
}
//实现cat功能:
#include<stdio.h>
int main(int argc, const char *argv[])
{
if(argc != 2)
{
printf("usage:%s <filename>\n",argv[0]);
return -1;
}
FILE *fp = fopen(argv[1],"r");
if(fp==NULL)
{
// printf("open fail");
perror("open fail");
return -1;
}
int ret;
while(EOF !=(ret=fgetc(fp)))
{
printf("%c",ret);
}
return 0;
}
#include<stdio.h>
int main(int argc, const char *argv[])
{
int ret;
while((ret = fgetc(stdin)) != EOF)
{
fputc(ret,stdout);
}
printf("ret = %d",ret);
return 0;
}
stdin 标准输入 从键盘输入
stdout 标准输出 在屏幕输出
stderr
//实现cp命令:
#include<stdio.h>
int main(int argc, const char *argv[])
{
if(argc!=3)
{
printf("err!\n");
return -1;
}
FILE *fp_src=fopen(argv[1],"r");
FILE *fp_dest=fopen(argv[2],"2");
if(fp_src==NULL)
{
perror("open fail!\n");
return -1;
}
int ret;
while((ret=fgetc(fp_src)) != EOF)
{
int dest = ret;
fputc(ret,fp_dest);
}
fclose(fp_src);
fclose(fp_dest);
return 0;
}
fgets/fputs
fgets:
char *fgets(char *s,int size,FILE *stream);
功能:从文件中读取数据,保存成一个字符串。
参数:
@s 表示存放字符串的空间的首地址
@size 表示最多读取size-1的个字符,因为最后一个字符是留给'/0';
@FILI *stream
fgets返回条件:
遇到'\n'
数组满了;
到达文件末尾;
成功:返回s
失败:返回NULL:
1,表示失败
2,到达文件结尾
//fgets统计文件中有多少个换行:\n
#include<stdio.h>
#include<string.h>
int main(int argc, const char *argv[])
{
int count = 0;
if(argc!=2)
{
printf("err,less");
return -1;
}
FILE *fp=fopen(argv[1],"r");
if(fp==NULL)
{
perror("open fail");
return -1;
}
char s[20];
// char *p;
while(fgets(s,sizeof(s),fp)!=NULL)
{
// p = fgets(s,sizeof(s),fp);
if(s[strlen(s)-1]=='\n');
count ++;
}
fclose(fp);
printf("%d\n",count);
return 0;
}
fputs:
int fputs(const char *s,FILE *stream)
功能:
输出字符串数据s到stream中
参数:
@s 保存字符串的一块空间的首地址
@FILE *stream 流指针指向输出的文件
返回值:
成功:非负数
失败:EOF
ps:fgets和fputs拷贝“二进制文件”时,会出现问题,其中的\0会导致数据丢失
缓存:
行缓存:缓存1k,1024个字节,主要用于人机交互
刷新条件:
1,遇到\n
2,程序正常结束
3,缓冲区超越刷新
4,fflush强制刷新
#include<stdio.h>
#include<unistd.h>
int main()
{
printf("123");
while(1)
sleep(1);
return 0;
}
//不会输出123,123存在于输出缓存区
//会一直sleep
//想要输出需要加上\n
#include<stdio.h>
#include<unistd.h>
int main()
{
int i=0;
for(i;i<1024;i++)
{
fputc('a',stdout);
}
return 0;
}
//不会输出,缓存区刚好够用
//i<1025时,缓冲区刷新
#include<stdio.h>
#include<unistd.h>
int main()
{
printf("123");
fflush(stdout);
while(1)
sleep(1);
return 0;
}
//会输出
//fflush()刷新输出缓冲区
全缓存:缓存区大小4k,主要用于文件处理
对 文件操作一般建立全缓存
刷新条件:
缓存区满刷新
程序结束刷新
fflush强制刷新
无缓存:缓存区大小:0k 一般用于 错误 输出
fflush:
#include<stdio.h>
#include<unistd.h>
int main()
{
printf("123");
fflush(stdout);
while(1)
sleep(1);
return 0;
}
//输出缓存区被刷新
//ps:fllush()不能刷新输入缓存区stdin
fread/fwrite:按对象读写
fread:
size_t fread(void *ptr,size_t size,size_t nmemb,FILE* stream)
//ps:读到最后没有一个完整对象时,停止读取,fread结束
返回值:
成功:返回成功读取单位对象大小的个数
失败:返回0
参数:
@ptr 存放数据的一块空间
@size 单个对象的大小
@stream 操作到的文件
文件偏移函数::
int fseek(FILE* stream,long offset,int whence);
功能:设置文件指示器位置
参数:
@stream 操作的文件流指针
@offset 偏移量
@whence 基点,有三个默认值
SEEK_SET 非负数,只能向后偏移
SEEK_CUR
SEEK_END
返回值:
成功 0
失败 -1 & errno
定位到开头:
fseek(fp,0,SEEK_SET); <==> rewind()
定位到末尾:
fseek(fp,0,SEEK_END);
空洞文件:可以强制占用磁盘空间
ftell:获得offset
long ftell(FILE* stream);
栗子:
//获得文件的长度:
#include<stdio.h>
int main ()
{
FILE* fp = fopen("xxx","r");
fseek(fp,0,SEEK_END);
long len = ftell(fp);
printf("len of file:%l",len);
return 0
}
栗子:
创建空洞文件,再创建一个跟空洞文件大小一样的文件:
#include<stdio.h>
int main(int argc, const char *argv[])
{
FILE *fp = fopen("kong","w");
fseek(fp,100,SEEK_SET);
fputc('a',fp);
long len = ftell(fp);
FILE *fp1 =fopen("kong2","w");
int i=0;
printf("%ld\n",len);
for(i=0;i<len;i++)
{
fputc('b',fp1);
}
fclose(fp);
fclose(fp1);
return 0;
}
栗子:仿实现迅雷下载,下载前占用空间,根据src文件大小下载dest文件
#include<stdio.h>
#include<stdlib.h>
int main(int argc, const char *argv[])
{
/*
if(argc!=3)
{
printf("err input");
return -1;
}
*/
FILE *fp_src=fopen("src.txt","r");
FILE *fp_dest=fopen("download.txt","w");
if(fp_src==NULL || fp_dest==NULL)
{
perror("err!");
return -1;
}
//获得src文件的长度
fseek(fp_src,0,SEEK_END);
long len = ftell(fp_src);
printf("len = %ld\n",len);
// 创建空洞文件
fseek(fp_dest,len-1,SEEK_SET);
fputc(0,fp_dest);
// 重置偏移
rewind(fp_src);
rewind(fp_dest);
// 开始拷贝
char *p = malloc(len);
fread(src,len,1,fp_src);
fwrite(src,len,1,fp_dest);
//关闭文件
fclose(fp_src);
fclose(fp_dest);
/*
char s[100]={0};
while((fgetc(s,sizeof(s),fp_src))!=NULL)
{
fputc(s,fp_dest);
}
//实现copy功能
*/
return 0;
}
总结:
1,标准IOh函数
2,文件操作:
打开:fopen()
读写:
fgetc/fputc()
fgets/fputs()
fread/fwrite()
定位:
fseek()
ftell()
rewind()
关闭:
fclose()
其他函数:
feof() //判断流是结尾
ferror()//判断流是否出错
#include<stdio.h>
int main(int argc, const char *argv[])
{
int ret;
while((ret = fgetc(stdin))!=EOF)
{
fputc(ret,stdout);
}
printf("ret = %d\n",ret);
if(feof(stdin))
{
printf("end of file\n");
}else if(ferror(stdin)){
printf("stdin error\n");
}
return 0;
}
系统调用文件IO:
不带缓存
操作对象:文件描述符(整数)
系统调用文件有哪些函数?
open()
close();
read();
write();
lseek();
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_APPEND 追加
O_CREAT 不存在时创建
O_TRUNC 截断长度为0的文件
组合:"a":O_WRONLY | O_APPEND
@mode
只有在O_CREAT时,
定义被创建文件的权限
返回值:
成功:非负的整型数值
失败:-1 & noerr
read:
ssize_t read(int fd, void *buf,size_t count)
功能:从 文件描述符 中读取数据
参数:
@fd 要读取的文件 对应的 文件描述符
@buf 存放到内存的一块空间的地址
@count 一次期望读取的最大字节数
返回值:
成功: 返回成功读取了 字节数 0代表end of file
失败: 返回 -1 & noerror
ps:会读取'\n'
读取字符串需要添加'\0',否则有残留。
write:
ssize_t write(int fd,const void*buff,size_ count);
功能:将数据 写到文件
参数:
~
~
count:一次写操作 写入的字节数
返回值:
成功:返回写入成功的字节数
失败:-1 & noerr
read write open 实现cp功能:
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include<stdio.h>
int main(int argc, const char *argv[])
{
if(argc!=3)
{
printf("err\n");
return -1;
}
int fd_src = open(argv[1],O_RDONLY);
int fd_dest = open (argv[2],O_WRONLY);
if(fd_src<0||fd_dest<0)
{
perror("open fail\n");
return -1;
}
char buf[100];
int ret=0;
while( ret = read(fd_src,buf,sizeof(buf)))
{
write(fd_dest,buf,ret);
}
close(fd_src);
close(fd_dest);
return 0;
}
标准IO中使用文件IO函数:
fileno:测试流指针,并转换流指针返回一个整型的文件描述符
int main()
{
FILE* fp = FILE("1.txt","r");
int fd = fileno(fd);
}
文件IO中使用标准IO函数:
fdopen:将文件描述符转换成流指针
int main()
{
int fd=open("1.txt",O_RDONLY);//
if(fd<0)
{
perror("open fail");
return -1;
}
FILE *fp=fdopen(fd,"r");//这里打开方式权限需要小于等于之前open的打开权限,否则会报错
if(fp=NULL)
{
perror("fopen fail");
return -1;
}
}
文件操作指目录文件:
opendir:打开一个流与目标目录对应,返回值是一个指针 DIR *,指向目录流,并定位在目录入口哦
失败返回NULL
eg:opendir("/home/linux/res");
//使用opendir readdir 实现ls -i的功能:
int main ()
{
DIR *dirp = opendir("123");//目录需要存在
if(dirp == NULL)
{
perrpr("open fail");
return -1;
}
struct dirent *pdir = NULL;
// int i=0;
while(pdir=readdir(dirp))
{
printf("ino:%d name:%s",pdir->d_ino,pdir->d_name);
}
// printf("")
}
struct dirent *readdir(DIR* dirp);
功能:
从目录流中读取文件信息,并保存信息的结构体
参数:
dirp:目录流指针
返回值:
成功:包含文件信息的结构体
失败:出错或者读到目录流末尾返回 NULL
栗子:统计目录中 常规文件 和 目录文件的个数:
#include<stdio.h>
#include <sys/types.h>
#include <dirent.h>
int main(int argc, const char *argv[])
{
DIR *dp = opendir("/home/linux/shell/dir");
if(dp==NULL)
{
perror("open fail");
return -1;
}
struct dirent *pdir = NULL;
int cnt_REG=0;
int cnt_DIR=0;
while(pdir=readdir(dp))
{
if(pdir->d_type==DT_REG)
{
cnt_REG++;
}else if(pdir->d_type==DT_DIR)
{
cnt_DIR++;
}
}
closedir(dp);
printf("REG:%d DIR:%d\n",cnt_REG,cnt_DIR);
return 0;
}
linux@ubuntu:~/shell/dir$ l -l total 20 -rw-rw-r-- 1 linux linux 0 5月 29 14:08 1.txt -rw-rw-r-- 1 linux linux 0 5月 29 14:08 2.txt -rw-rw-r-- 1 linux linux 0 5月 29 14:08 3.txt -rwxrwxr-x 1 linux linux 8488 5月 29 14:25 a.out* -rw-rw-r-- 1 linux linux 472 5月 29 14:24 file_type.c drwxrwxr-x 2 linux linux 4096 5月 29 14:21 one/
说明drwxrwxr-x 2 linux linux 4096 5月 29 14:21 one/这列Linux代码中数字***2***的含义:
1,当文件是目录文件时,数字代表该目录下有几个子目录(包含.和…)
2,当文件是非目录文件时,数字代表该文件内容有几个 硬链接。
硬链接 :给文件取别名
ln 源文件名 硬链接文件名
与源文件直接关联。iNode号与源文件相同,修改一个,另一个同时被修改,但删除其中一个不会影响另一个文件,大小与源文件相同。
特点:
1,不占硬盘空间
2,不能对目录进行操作
3,不能跨文件系统
软链接 :相当于Windows中的快捷方式,用来记录我们目标的路径
ln -s 源文件名 软链接名
不与源文件关联,大小与源文件不同,一般为软链接自身文件大小。
特点:
1,占用磁盘空间
2,可以对目录操作
3,可以跨文件系统
创建硬链接和软链接:
硬链接:ln a.out hard_link
-rwxrwxr-x 2 linux linux 8488 5月 29 14:25 a.out*
-rwxrwxr-x 2 linux linux 8488 5月 29 14:25 hard_link*
软链接:ln -s a.out soft_link
-rwxrwxr-x 2 linux linux 8488 5月 29 14:25 a.out*
lrwxrwxrwx 1 linux linux 5 5月 29 14:55 soft_link -> a.out*
文件类型相关权限 目录 用户名 所在组 文件大小 最后被修改时间 文件名
stat函数:返回一个文件的信息
int stat(const char *path,struct stat *buf);
功能:
参数:
@const char *path 文件路径
@struct stat *buf
打印指定文件的iNode
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
int main(int argc, const char *argv[])
{
/*
DIR* dp = opendir("/home/linux/shell/dir");
if(dp == NULL)
{
perror("open dir fail");
return -1;
}
*/
struct stat statbuf;
stat(argv[1],&statbuf);
printf("inode = %ld\n",statbuf.st_ino);
return 0;
}
实现目录拷贝
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
//cp src dest
int do_cp_file(const char *src, const char * dest)
{
int fd_s = open(src,O_RDONLY);
int fd_d = open(dest,O_WRONLY|O_CREAT|O_TRUNC,0666);
if (fd_s < 0 || fd_d < 0)
{
perror("open fail");
return -1;
}
off_t len = lseek(fd_s,0,SEEK_END);
lseek(fd_d,len-1,SEEK_SET);
write(fd_d,"",1);
lseek(fd_s,0,SEEK_SET);
lseek(fd_d,0,SEEK_SET);
char buf[len];
read(fd_s,buf,len);
write(fd_d,buf,len);
close(fd_s);
close(fd_d);
return 0;
}
int do_cp_dir(const char *dir1,const char *dir2)
{
//1.opendir
DIR *dir = opendir(dir1);
if (dir == NULL)
{
perror("opendir fail");
return -1;
}
struct dirent *pdir = NULL;
while (pdir = readdir(dir))
{
// . ..
//
//src
// |--1.txt
// |--dir1
// | |--2.txt
// |--3.c
if (strcmp(pdir->d_name,".")!=0&&strcmp(pdir->d_name,"..")!=0)
{
char spath[1024] = {0};
char dpath[1024] = {0};
dir1[strlen(dir1)-1] == '/'?sprintf(spath,"%s%s",dir1,pdir->d_name):sprintf(spath,"%s/%s",dir1,pdir->d_name);
dir2[strlen(dir1)-1] == '/'?sprintf(dpath,"%s%s",dir2,pdir->d_name):sprintf(dpath,"%s/%s",dir2,pdir->d_name);
printf("src = %s\n",spath);
printf("dest = %s\n",dpath);
//mkdir
if (pdir->d_type == DT_DIR)
{
mkdir(dpath,0777);
do_cp_dir(spath,dpath);
}else
{
do_cp_file(spath,dpath);
}
}
}
return 0;
}
//./a.out d_src d_dest
//./a.out src dest
int main(int argc, const char *argv[])
{
if (argc != 3)
{
printf("Usage: %s <dir1> <dir2>\n",argv[0]);
return -1;
}
mkdir(argv[2],0777);
do_cp_dir(argv[1],argv[2]);
return 0;
}
小插曲:
chdir:改变当前工作目录
在C语言中,chdir函数用于更改当前工作目录。它的作用是将当前进程的工作目录更改为指定的目录。
chdir函数的原型为:
#include <unistd.h>
int chdir(const char *path);
参数path是要设置为新的当前工作目录的路径名。
如果调用成功,则返回0,否则返回-1并设置errno变量来指示出错的原因。常见的错误原因包括无法访问指定目录、路径名过长等等。
C语言中mkdir函数用于创建一个新的目录(文件夹)。
具体来说,该函数的作用是在指定的路径上创建一个包含指定权限的新目录。如果成功创建了目录,则返回0,否则返回-1并设置errno错误代码。
例如,下面的代码将在当前目录下创建名为“testdir”的新目录:
#include <sys/stat.h>
#include <sys/types.h>
int main()
{
char* dirname = "testdir";
int status = mkdir(dirname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
if (status != 0) {
// 处理失败情况
return -1;
}
// 处理成功情况
return 0;
}
其中,第二个参数S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH表示为新目录指定了读取、写入和执行权限,这意味着用户、组和其他人都可以读取、写入和执行此目录。
getcwd() 是一个C标准库函数(stdlib.h 或 unistd.h 在头文件),通过调用该函数可以获取当前工作目录的路径名。 getcwd() 函数的原型如下所示:
c
#include <unistd.h>
char *getcwd(char *buf, size_t size);
buf:输出参数,代表了指向储存路径名称的内存地址。
size:缓冲区指针 buf 的大小。
在函数执行成功时,返回值指向包含当前工作目录字符串 (总长度不大于n) 的指针;如果失败,则返回 NULL,错误信息可由 errno 获取。
例如:
c
char buff[FILENAME_MAX];
getcwd(buff, FILENAME_MAX);
printf("Current working dir: %s\n", buff);
其中 buff 是自己定义的一个字符数组,FILENAME_MAX 是表示该数组空间的最大容量,即缓冲区的大小。
rmdir是C语言中的一个函数,用于删除指定目录。
rmdir用于删除空目录
具体来说,当调用 rmdir(dirname) 时,它会尝试删除给定名称的空目录。如果该目录包含子目录或文件,则该操作将失败并显示相应的错误信息。
以下是使用rmdir函数来删除目录的示例:
#include <stdio.h>
#include <unistd.h>
int main() {
char dirname[] = "mydir";
if (rmdir(dirname) == 0)
printf("目录 %s 删除成功\n", dirname);
else
printf("目录 %s 删除失败\n", dirname);
return 0;
}
在上面的示例中,我们首先定义了要删除的目录的名称(即“mydir”),然后通过调用rmdir函数来尝试删除该目录。如果删除成功,则输出“目录 mydir 删除成功”,否则输出“目录 mydir 删除失败”。
stat,fstat,lstat:
这三个函数的主要区别在于它们分别适用于哪种类型的文件描述符。
stat() 函数 适用于传入一个表示文件名的字符串参数。通过该函数可以获取了与文件相关的所有信息,包括文件大小、创建时间、修改时间等等。
fstat() 函数 适用于传入一个文件描述符参数(即已经打开的文件)。可用于在不知道文件名的情况下获取相应文件的所有信息。
lstat() 函数 与 stat() 类似,但是在遇到符号链接时会返回链接本身的所有信息,而不是被链接的目标文件所对应的信息。
access
函数的第二个参数mode
指定了检查文件是否存在、是否具有读权限、是否具有写权限等操作。它可以是以下几种值的按位或(“|”)操作:
F_OK
:用于判断文件是否存在;R_OK
:用于判断文件是否可读;W_OK
:用于判断文件是否可写;X_OK
:用于判断文件是否可执行。
例如,如果我们想要判断文件是否存在且可读,则可以使用F_OK | R_OK
作为mode
参数传递给access
函数。以下是一个示例代码:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
if (argc < 2) {
fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
return 1;
}
if (access(argv[1], F_OK | R_OK) == 0) {
printf("File '%s' exists and is readable.\n", argv[1]);
return 0;
} else {
printf("File '%s' does not exist or is not readable.\n", argv[1]);
return 1;
}
}
在上述代码中,我们将mode
参数设置为F_OK | R_OK
,表示要检查文件是否存在且可读。如果文件存在且可读,则返回0,否则返回-1并设置errno变量。
S_ISDIR
的实现通常是使用位运算实现的。具体地说,它使用了一个叫作S_IFMT
的宏,该宏定义了文件类型(file type)的掩码(mask)。S_IFMT
与mode
进行按位与运算后,可以得到mode
值中文件类型部分的值。然后,S_ISDIR
将这个值与S_IFDIR
比较,如果相等,则返回true
,否则返回false
。
实现cp(复制文件)功能时,涉及到数据读写的操作。在选择将哪些函数用于实现cp功能时,需要考虑它们的效率和性能。下面对每个函数的效率进行简单分析。
fread
和fwrite
函数
fread
和fwrite
函数是C标准库中用于二进制数据读写的函数。它们在处理大量数据时,比使用一次一个字符读取或写入数据要快得多,并且可以提高整个系统的效率。因此,在处理大量数据时使用它们的效率是非常高的。但是,它们无法处理包含二进制数据的文本文件,并且不支持Unicode编码。
read
和write
函数
read
和write
函数是UNIX系统API中用于读写数据的函数。与fread
和fwrite
函数类似,它们可以处理大量数据。如果需要处理大文件,则使用read
和write
函数的效率更高。使用这些函数时,需要注意文件描述符的使用,因为它们是UNIX API的一部分,而不是C标准库的一部分。
fgets
和fputc
函数
fgets
和fputc
函数是C标准库中用于文本文件读写的函数。它们可以处理包含文本数据的文件,并且支持Unicode编码。但是,因为它们需要依次读取或写入每个字符,因此在处理大量数据时会出现效率低的问题。
fgetc
和putchar
函数
fgetc
和putchar
函数也是C标准库中用于文本文件读写的函数。虽然它们比fgets
和fputc
函数更高效,但是在读取或写入大量数据时仍然会存在性能问题。
综上所述,如果需要处理大量的二进制数据,则最好使用fread
和fwrite
函数或read
和write
函数;如果处理文本文件,则选择fgets
和fputc
函数可以保持代码可读性,但在性能方面表现较差,而fgetc
和putchar
函数则更高效一些。需要根据具体情况进行选择。
更多推荐
所有评论(0)