目录
文件IO
1、概念
遵循POSIX标准,文件IO是通过系统调用函数直接操作文件
2、文件描述符
在文件IO中,一个文件对应了一个文件描述符。cx在此
本质:文件描述符是一个由系统自动分配的最小的非负整数,当用户创建或者打开一个文件时,系统会向当前进程返回一个文件描述符。
文件IO相关系统调用函数
1、打开或者新建文件 —— open
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>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_CREAT:如果文件不存在,则新建该文件
O_EXCL:通常和O_CREAT结合使用,用于判断文件是否存在
O_TRUNC: 打开文件时,先清空文件内容
O_APPEND:以追加的方式打开文件,所有对文件的写操作默认在文件末尾进行
mode:当用户需要创建新文件时,使用O_CREAT选项创建,并使用该参数给新文件赋初始权限
//默认0664
返回值:
成功返回文件描述符,失败返回-1
umask:文件权限掩码
最终文件权限 == 初始权限 & (~umask)
eg
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int fd = open("1.txt",O_RDONLY);
if(fd < 0)
{
perror("open 1.txt");
exit(-1);
}
printf("成功打开文件fd = %d\n",fd);
return 0;
}
ie
2、关闭文件 —— close
#include <unistd.h>
int close(int fd);
参数:
fd:文件描述符
eg
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int fd = open("1.txt",O_RDONLY); //打开文件
if(fd < 0)
{
perror("open 1.txt");
exit(-1);
}
printf("成功打开文件fd = %d\n",fd);
close(fd); //关闭文件
return 0;
}
ie
3、读文件 —— read
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
参数:
fd:文件描述符
buf:存储读取内容的首地址
count:请求读取的字节数
返回值:
(1)成功返回读取的字节数,(2)失败返回-1,(3)0表示读到文件末尾
eg
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[])
{
int fd = open("1.txt",O_RDONLY);
if(fd < 0)
{
perror("open 1.txt");
exit(-1);
}
char arr[32] = {0};
int ret = read(fd, arr, 17);
if(ret < 0)
{
perror("read");
exit(-1);
}
printf("ret=%d arr=%s\n",ret,arr);
close(fd);
return 0;
}
ie
4、写文件 —— write
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
参数:
fd:文件描述符
buf:存储写入内容的首地址
count:请求写入的字节数
返回值:
成功返回写入的字节数,失败返回-1
eg
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[])
{
int fd = open("1.txt",O_WRONLY);
if(fd < 0)
{
perror("open 1.txt");
exit(-1);
}
char arr[64] = {0};
fgets(arr,64,stdin);
int ret = write(fd,arr,strlen(arr));
if(ret < 0)
{
perror("write");
exit(-1);
}
close(fd);
return 0;
}
ie
5、文件定位 —— lseek
#include <sys/types.h>
#include <unistd.h>off_t lseek(int fd, off_t offset, int whence);
参数:
fd:文件描述符
offset:偏移量,可正可负,正表示向后偏移,负表达向前偏移
whence:基准点
SEEK_SET:文件开头
SEEK_CUR:文件指针当前位置
SEEK_END:文件末尾返回值:
成功返回文件指针当前位置相对于文件开头的偏移量,失败返回-1
eg
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[])
{
int fd = open("1.txt",O_WRONLY);
if(fd < 0)
{
perror("open 1.txt");
exit(-1);
}
lseek(fd,0,SEEK_END);
char arr[64] = {0};
fgets(arr,64,stdin);
int ret = write(fd,arr,strlen(arr));
if(ret < 0)
{
perror("write");
exit(-1);
}
close(fd);
return 0;
}
ie
目录操作
1、打开目录 —— opendir
#include <sys/types.h>
#include <dirent.h>DIR *opendir(const char *name);
参数:
name:目录名
返回值:
成功返回目录流指针,失败返回NULL;
eg
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
//打开目录
DIR *dir = opendir(".");
if(NULL == dir)
{
perror("opendir");
exit(-1);
}
printf("打开成功\n");
//colsedir(dir);
return 0;
}
ie
2、关闭目录 —— closedir
#include <sys/types.h>
#include <dirent.h>int closedir(DIR *dirp);
参数:
dirp:目录流指针
eg
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
//打开目录
DIR *dir = opendir(".");
if(NULL == dir)
{
perror("opendir");
exit(-1);
}
printf("打开成功\n");
//关闭目录
closedir(dir);
return 0;
}
ie
3、读取目录项 —— readdir
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
返回值:
成功返回一个目录项的信息,失败或者读完返回NULLstruct dirent {
ino_t d_ino; /* Inode number */
off_t d_off; /* Not an offset; see below */
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]; /* Null-terminated filename */
};
eg
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
//打开目录
DIR *dir = opendir(".");
if(NULL == dir)
{
perror("opendir");
exit(-1);
}
//读取目录项
struct dirent *dt = NULL;
while(NULL != (dt = readdir(dir)))
{
if(dt->d_name[0] != '.')//不打印隐藏文件
printf("%s ",dt->d_name);
}
putchar('\n');
//关闭目录
closedir(dir);
return 0;
}
ie
4、文件属性获取 —— stat、fstat、lstat
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>int stat(const char *pathname, struct stat *statbuf);
int fstat(int fd, struct stat *statbuf);
int lstat(const char *pathname, struct stat *statbuf);
参数:
pathname:文件名
statbuf:文件属性相关结构体的首地址
返回值:
成功返回0,失败返回-1
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* Inode number */
mode_t st_mode; /* File type and mode */
nlink_t st_nlink; /* Number of hard links */
uid_t st_uid; /* User ID of owner */
gid_t st_gid; /* Group ID of owner */
dev_t st_rdev; /* Device ID (if special file) */
off_t st_size; /* Total size, in bytes */
blksize_t st_blksize; /* Block size for filesystem I/O */
struct timespec st_atim; /* Time of last access */
struct timespec st_mtim; /* Time of last modification */
struct timespec st_ctim; /* Time of last status change */#define st_atime st_atim.tv_sec /* Backward compatibility */
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
}
文件类型:
eg:
st_mode & S_IFMT == S_IFREG //表示该文件为普通文件
S_IFMT 0170000 bit mask for the file type bit fieldS_IFSOCK 0140000 socket
S_IFLNK 0120000 symbolic link
S_IFREG 0100000 regular file
S_IFBLK 0060000 block device
S_IFDIR 0040000 directory
S_IFCHR 0020000 character device
S_IFIFO 0010000 FIFO文件权限:
eg:
if(st_mode & S_IRUSR) //如果结果为真,表示具有该权限
{
pritnf("r");
}
else
{
printf("-");
}S_IRUSR 00400 owner has read permission
S_IWUSR 00200 owner has write permission
S_IXUSR 00100 owner has execute permissionS_IRGRP 00040 group has read permission
S_IWGRP 00020 group has write permission
S_IXGRP 00010 group has execute permissionS_IROTH 00004 others have read permission
S_IWOTH 00002 others have write permission
S_IXOTH 00001 others have execute permission
通过用户ID得到用户名:
#include <sys/types.h>
#include <grp.h>
struct group *getgrgid(gid_t gid);
通过用户组ID得到用户组名:
#include <sys/types.h>
#include <pwd.h>struct passwd *getpwuid(uid_t uid);
eg
#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include <dirent.h>
#include <fcntl.h>
#include <grp.h>
#include <pwd.h>
int main(int argc, char *argv[])
{
char *arr[64] = {0};
char *tmp = NULL;
int len =0;
int i = 0;
int j = 0;
int a = 0;
//1、打开目录
DIR *dp = opendir(".");
if(NULL == dp)
{
perror("opendir");
return -1;
}
//2、列出所以目录名
struct dirent *dt = NULL;
while((dt = readdir(dp)) != NULL)
{
//3、不显示隐藏文件
if(dt->d_name[0] !='.')
{
arr[a] = dt->d_name;
len ++;
a++;
}
}
//4、排序
for(i = 0; i < len-1; i++)
{
for(j = 0; j < (len-1)-i; j++)
if(strcmp(arr[i],arr[i+1]) > 0)
{
tmp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = tmp;
}
}
//5、列出详细信息
struct stat info;
struct tm*myt = NULL;
//6、所以的民字都赋给结构体
for (i = 0; i < len; i++ )
{
lstat(arr[i],&info);
//7、时间
myt = localtime(&info.st_mtime);
switch(info.st_mode & S_IFMT)
{
case S_IFREG:
printf("-"); break;
case S_IFLNK:
printf("l"); break;
case S_IFSOCK:
printf("s"); break;
case S_IFIFO:
printf("p"); break;
case S_IFBLK:
printf("b"); break;
case S_IFCHR:
printf("c"); break;
case S_IFDIR:
printf("d"); break;
}
char arr1[4] = {'x','w','r','-'};
for(j = 8; j>=0; j--)
{
if(info.st_mode & (S_IXOTH << j))
{
printf("%c",arr1[j%3]);
}
else
{
printf("%c",arr1[3]);
}
}
struct group *gid = NULL;
struct passwd *uid = NULL;
gid = getgrgid(info.st_gid);
uid = getpwuid(info.st_uid);
printf("%s %s",gid->gr_name,uid->pw_name);
//、打印
printf("%ld %ld %d月 %d %02d:%02d %s\n",info.st_nlink, info.st_size, myt->tm_mon+1, myt->tm_mday, myt->tm_hour, myt->tm_min, arr[i]);
}
//、关闭目录
closedir(dp);
return 0;
}
ie