文件IO操作、目录操作
一、文件IO操作
1.利用read和write实现复制功能
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char **argv) // ./a.out 1 2
{if(argc<3){ printf("usage:./a.out srcfile dstfile\n");return 1;}int srcfd = open(argv[1],O_RDONLY);int dstfd = open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0666);if(-1 == srcfd || -1 == dstfd){printf("open error\n");return 1;}while(1){char buf[1024]={0};int ret = read(srcfd,buf,sizeof(buf));if(0==ret){break;}write(dstfd,buf,ret);}close(dstfd);close(srcfd);return 0;
}
2.strtok函数
strtok 函数是 C 语言标准库中用于分割字符串的函数。它的作用是将一个字符串根据指定的分隔符分割成多个子字符串。
函数原型
char *strtok(char *str, const char *delim);
- str 是要分割的原始字符串。在第一次调用 strtok 时,str 应指向待分割的字符串。在随后的调用中,str 应该设置为 NULL。
- delim 是一个包含所有分隔符的字符串。每次调用 strtok 时,它都会返回下一个分割出的子字符串。如果没有更多的子字符串可以检索,它将返回 NULL。
#include <string.h>
#include <stdio.h>
int main () {char str[80] = "This is - www.runoob.com - website";const char s[2] = "-";char *token;/* 获取第一个子字符串 */token = strtok(str, s);/* 继续获取其他的子字符串 */while( token != NULL ) {printf( "%s\n", token );token = strtok(NULL, s);}return(0);
}
3.fileno函数
fileno函数是一个在C语言中常用的函数,它的主要功能是将文件流指针转换为文件描述符。文件描述符是一个整数值,它在底层系统调用中代表了一个打开的文件。在Linux编程中,文件描述符是一个重要的概念,因为它提供了对文件的低级访问。
fileno函数的定义和使用
在C语言中,fileno函数的原型定义在<stdio.h>头文件中,其函数原型为:
int fileno(FILE *stream);
int main(int argc, char **argv)
{FILE* fp = fopen("1.txt","w");if(NULL == fp){return 1;}int fd = fileno(fp);write(fd,"hello",5);fclose(fp);return 0;
}
4.lseek函数
lseek函数是Linux系统编程中用于移动文件读写位置的函数。它的作用是重新定位文件内的读写位置,这个位置是从文件开头到当前位置的字节数。
lseek函数的原型如下:
#include <sys/types.h>#include <unistd.h>off_t lseek(int fd, off_t offset, int whence);
int main(int argc, char **argv)
{int fd = open("1.txt",O_WRONLY|O_CREAT|O_TRUNC,0666);if(-1 == fd){printf("open error");return 1;}off_t offset = lseek(fd,1024*1024*10,SEEK_SET);printf("%ld\n",offset);write(fd,"a",2);close(fd);return 0;
}
5.fdopen函数
fdopen函数是C语言中的一个标准I/O库函数,它的作用是将一个已有的文件描述符(file descriptor)转换为对应的文件指针(FILE *)。这个函数在进行文件操作时非常有用,特别是在需要将底层的文件描述符转换为高级的文件流操作时。
fdopen函数的原型定义如下:
#include <stdio.h>FILE *fdopen(int fd, const char *mode);
int main(int argc, char **argv)
{int fd = open("1.txt",O_RDONLY);if(-1 == fd){return 1;}FILE* fp = fdopen(fd,"r");if(NULL == fp){return 1;}char buf[512]={0};fgets(buf,sizeof(buf),fp);printf("%s",buf);fclose(fp);return 0;
}
6.perror函数
perror函数是一个用于错误处理的库函数,它的作用是将上一个函数发生错误的原因输出到标准错误输出(stderr)。C 库函数 void perror(const char *str) 首先输出字符串 str,后跟一个冒号,然后是一个空格。
perror的工作原理:当一个系统调用或库函数发生错误时,通常会将全局变量errno
设置为一个特定的错误码。perror函数读取errno的值,并根据这个值生成相应的错误描述。然后,将错误描述与传入的字符串参数拼接,并输出到标准错误流。
int main(int argc, char **argv)
{perror("aaa");FILE* fp = fopen("10.txt","r");if(NULL == fp){printf("errno %d\n",errno);perror("fopen main.c:10");return 0;}return 0;
}
二、目录操作
1.打开目录 opendir
opendir()函数原型如下所示:
#include <sys/types.h>
#include <dirent.h>DIR *opendir(const char *name);
函数参数和返回值含义如下:
- name:指定需要打开的目录路径名,可以是绝对路径,也可以是相对路径。
- 返回值:成功将返回指向该目录的句柄,一个 DIR 指针(其实质是一个结构体指针),其作用类似于open函数返回的文件描述符fd,后续对该目录的操作需要使用该DIR指针变量;若调用失败,则返回NULL。
2.读取目录 readdir
readdir()用于读取目录,获取目录下所有文件的名称以及对应 inode 号。这里给大家介绍的 readdir()是一个 C 库函数(事实上 Linux 系统还提供了一个 readdir 系统调用),其函数原型如下所示:
#include <dirent.h>struct dirent *readdir(DIR *dirp);
函数参数和返回值含义如下:
- dirp:目录句柄 DIR 指针。
- 返回值:返回一个指向 struct dirent 结构体的指针,该结构体表示 dirp 指向的目录流中的下一个目录条目。在到达目录流的末尾或发生错误时,它返回 NULL。
struct dirent 结构体内容如下所示:
struct dirent {ino_t d_ino; /* inode 编号 */off_t d_off; /* not an offset; see NOTES */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]; /* 文件名 */
};
3.关闭目录 closedir 函数
closedir()函数用于关闭处于打开状态的目录,同时释放它所使用的资源,其函数原型如下所示:
#include <sys/types.h>
#include <dirent.h>int closedir(DIR *dirp);
函数参数和返回值含义如下:
- dirp:目录句柄。
- 返回值:成功返回 0;失败将返回-1,并设置 errno。
int main(int argc, char **argv)
{DIR *dir = opendir("../");if (NULL == dir){perror("opendir"); // stderrreturn 1;}while (1){struct dirent *info = readdir(dir);if (NULL == info){break;}printf("%s\t\t", info->d_name);switch (info->d_type){case DT_BLK:printf("块设备\n");break;case DT_DIR:printf("目录文件\n");break;case DT_REG:printf("普通文件\n");break;default:printf("其他文件\n");}}closedir(dir);// system("pause");return 0;
}