- 文件操作(续)
- 目录操作
一、文件操作
1. lseek
lseek 是一个用于在文件中移动文件指针的系统调用,通常用于在文件描述符所指向的文件中定位读取或写入的位置。它允许程序在文件中随机访问数据,而不是只能顺序读取或写入。
off_t lseek(int fd, off_t offset, int whence);
参数说明
fd:文件描述符,表示要操作的文件。
offset:偏移量,表示要移动的字节数。
whence:基准位置,决定偏移量的起始点。它可以是以下值之一:
SEEK_SET:从文件开头开始计算偏移量。
SEEK_CUR:从当前文件指针位置开始计算偏移量。
SEEK_END:从文件末尾开始计算偏移量。
返回值:
- 成功时,返回新的文件指针位置(从文件开头计算的字节数)。
- 失败时,返回
-1
并设置errno以指示错误。
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>
#include<unistd.h>
#include<string.h>
int main(int argc, char **argv)
{
int fd = open("1.txt", O_WRONLY|O_CREAT|O_TRUNC,0666);
if(-1==fd)
{
fprintf(stderr, "open error");
return 1;
}
off_t offset = lseek(fd, 1024, SEEK_SET);
printf("%ld\n",offset);
write(fd, "a", 2);
close(fd);
return 0;
}
2. fileno及其用法
fileno 是一个用于获取文件描述符的函数。它通常用于将标准库中的文件流(FILE*)转换为底层的文件描述符(int),以便在需要直接使用系统调用时使用。
fileno 函数在需要将标准库的文件操作与底层系统调用结合时非常有用。例如,当使用 fopen 打开文件后,可能需要使用 read 或 write 等系统调用进行更底层的操作,这时可以使用 fileno 获取文件描述符。
int fileno(FILE *stream);
参数
stream
:指向FILE
结构的指针,通常是通过fopen
、fclose
等函数打开的文件流。
返回值
- 成功时返回与
stream
关联的文件描述符。 - 如果
stream
无效,返回-1
并设置errno
。
#include<stdio.h>
#include <unistd.h>
int main(int argc, char **argv)
{
FILE*fp = fopen("2.txt", "w");
if(NULL==fp)
{
return 1;
}
int fd = fileno(fp);
write(fd, "hello", 5);
fclose(fp);
return 0;
}
3. fdopen及其用法
fdopen是一个用于将文件描述符(file descriptor)转换为文件流(FILE stream)的函数。它通常用于将低级 I/O 操作(如 open
、read
、write
等)与标准 I/O 库函数(如 fprintf、
fscanf
等)结合使用。
FILE *fdopen(int fd, const char *mode);
参数说明
- fd:文件描述符,通常由 open、pipe 等系统调用返回。
- mode:指定文件流的打开模式,与 fopen 的模式字符串相同,如 "r"(只读)、"w"(只写)、"a"(追加)等。
返回值
成功时返回一个指向 FILE 结构的指针,失败时返回 NULL,并设置 errno 以指示错误。
#include<stdio.h>
#include <unistd.h>
#include<fcntl.h>
int main(int argc, char **argv)
{
int fd = open("2.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;
}
5. perror及其用法
perror 是一个用于报告错误的标准库函数。它通常与系统调用(如 open、read、write 等)一起使用,当这些调用失败时,perror 可以帮助开发者快速定位问题。
#include <stdio.h>
#include <errno.h>
int main(int argc, char **argv)
{
FILE*fp = fopen("5.txt", "r");
if(NULL==fp)
{
printf("error %d\n",errno);
perror("fopen main.c:10");
}
return 0;
}
二、目录操作
步骤:
打开目标目录 -->读取目录-->关闭目录
1. opendir:
是一个用于打开目录的系统调用。它通常用于读取目录中的内容。opendir 函数在 POSIX 兼容的系统(如 Linux 和 Unix)中可用。
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);
参数
- name:要打开的目录的路径名。
返回值
- 成功时,返回一个指向DIR结构的指针,该结构表示打开的目录。
- 失败时,返回NULL,并设置
errno
以指示错误。
2. readir
是一个用于读取目录内容的系统调用或库函数,通常在类 Unix 系统中使用。它允许程序遍历目录中的文件和子目录。
readdir 函数通常与 opendir 和 closedir 一起使用。opendir 用于打开一个目录,readdir 用于读取目录中的条目,closedir 用于关闭目录。
readdir 的返回值
readdir 返回一个指向 struct dirent 的指针,该结构体包含目录项的信息。如果到达目录末尾或发生错误,readdir 返回 NULL。
struct dirent 的常见字段包括:
d_name:文件名或目录名。
d_type:文件类型(如普通文件、目录等)。
3. closedir
是一个用于关闭目录流的系统调用,通常在 Unix 和类 Unix 系统(如 Linux)中使用。它用于释放与opendir函数打开的目录流相关的资源。
#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);
参数
- dirp:指向DIR类型的指针,该指针通常由opendir函数返回,表示一个打开的目录流。
返回值
- 成功时返回 0。
- 失败时返回 -1,并设置errno以指示错误类型。
注意事项
- 在关闭目录流之前,确保已经完成了对目录的所有操作,否则可能会导致资源泄漏。
- 如果closedir调用失败,程序应适当处理错误,以避免后续操作受到影响。
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
int main(int argc, char **argv)
{
DIR*dir=opendir("../");
if(NULL==dir)
{
perror("opendir");
return 1;
}
while (1)
{
struct dirent*info= readdir(dir);
if(NULL==info)
{
break;
}
printf("%s\n",info->d_name);
}
closedir(dir);
return 0;
}
4. time
是一个用于获取当前时间的函数。它通常返回自 Unix 纪元(1970 年 1 月 1 日 00:00:00 UTC)以来的秒数。
time函数定义在<time.h> 头文件中。它的原型如下:
#include <time.h>
time_t time(time_t *tloc);
time函数返回当前时间,并将其存储在tloc指向的内存位置(如果tloc不是NULL)。time_t 是一个数据类型,通常是一个长整型,表示自 Unix 纪元以来的秒数。
可用local time函数 转化为具体的日期和时间。
#include <stdio.h>
#include <time.h>
int main(int argc, char **argv)
{
time_t tm;
tm =time(NULL);
printf("%ld\n",tm);
struct tm*tminfo = localtime(&tm);
printf("%d-%d-%d %d:%d:%d\n",tminfo->tm_year+1900,tminfo->tm_mon+1,tminfo->tm_mday
,tminfo->tm_hour,tminfo->tm_min,tminfo->tm_sec);
return 0;
}