系统IO
函数概述:
1. open close
2. write read size_t write(int fd,const void *buf,size_t count)
3. lseek(int fd,long offset,int origin)
4.dup dup2, int dup(int fd) int dup2(fd1,fd2)
5.time asctime, ctime, localtime,strltime,
6. int fileno(FILE *fp) FILE *fdopen(int fd)
7. stat
-
open close
int __cdecl open(const char *_Filename,int _OpenFlag,…) __MINGW_ATTRIB_DEPRECATED_MSVC2005;
以指定的方式打开文件,若成功,返回一个新的文件的描述符,失败返回-1文件描述符:每打开一个文件,就会用一个未被使用的最小的文件描述符来记录
文件描述符实际上就是数组的下标,范围从0开始到1023截止,一旦拿到文件描述符,就可以对相应的文件进行操作参数1 要打开的文件的路径
参数2 如下系统io的6种打开方式
O_RDONLY 0
O_WRONLY 1
O_RDWR 2
以上宏值是互斥的,一次可以使用一个,但可以或上其他的值
//标准IO:fopen,6种打开方式,/系统IO
r O_RDONLY; 只读
r+ O_RDWR 可读可写
w O_WRONLY|O_CREAT|O_TRUNC,0666
w+ O_RDWR|O_CREAT|O_TRUNC,0666
a O_WRONLY|O_CREAT|O_APPEND,0666
a+ O_WDWR|O_CREAT|O_APPEND,0666
//文件IO:
int open(const char* pathname,int flags)
O_RDONLY 只读
O_RDWR 可读可写
O_WRONLY 只写
O_CREATE 若文件不存在创建,并用第三个参数为其设置权限
O_TRUNC,0XXX 若文件已经存在,清零
O_APPEND 追加,在文件的末尾进行写操作
返回值:成功返回文件描述符
失败返回1并设置errno
2.close
int close(int fildes)
3.read
ssize_t read(int fd,void *buf,size_t count)
int fd ,open的返回值,buf缓冲区接收数据,count 读取的最大字节数
4.write
ssize_t write(int fd,const char* buf,size_f count)
- write read size_t write(int fd,const void *buf,size_t count)
3.read
ssize_t read(int fd,void *buf,size_t count)
int fd ,open的返回值,buf缓冲区接收数据,count 读取的最大字节数
4.write
ssize_t write(int fd,const char* buf,size_f count)
- lseek(int fd,long offset,int origin)
off_t lseek(int fd,long _Offset,int whence)
offset:相对基准点whence的偏移量。一字节为单位,正数表示向前移动(往文件结尾方向偏移),负数表示向后移动
whence :当前位置的基点 1. SEEK_SET 文件的起始位置
2.SEEK_CUR 文件当前读取位置
3.SEEK_END 文件的结束位置
return value:成功返回文件当前读取的位置
失败返回文件结束位置
4文件描述符重定向.dup dup2
文件描述符重定向:
int dup(int oldfd);//复制文件描述符,作用就是让一个文件拥有多个文件描述符,失败返回-1
语法:
int fd2;
fd2 = dup(fd1);//让fd2也来记录fd1保存的文件
注意:dup不是原子操作,不建议使用
原子操作:不可分割的操作方式,用来解决多进程多线程竞争
int dup2(int oldfd, int newfd);//文件描述符重定向
//成功,将新文件描述符返回出去,如果失败,返回-1
如果newfd已经记录了一个文件,此时关闭newfd记录的文件,重定向到oldfd记录的文件
将参数二的fd2去保存参数一fd1记录的文件
- int fileno(FILE *fp) FILE *fdopen(int fd)
6…time asctime, ctime, localtime,strltime,
#include <stdio.h>
#include <time.h>
/*
时间函数相关的结构体
struct tm {
int tm_sec; seconds
int tm_min; minutes
int tm_hour; hours
int tm_mday; day of the month
int tm_mon; month
int tm_year; year
int tm_wday; day of the week
int tm_yday; day in the year
int tm_isdst; daylight saving time
};
The members of the tm structure are:
*/
int main()
{
struct tm *tm1,*p;
char *tm2;
long t;
while (1)
{
t = time(NULL);//获取当前时间
printf("%ld\n",t);
sleep(1);
char *ret;
ret = ctime(&t);//依当前时间t获取一段关于时间的字符串:如下eg
printf("%s\n",ret);//eg:Fri Sep 20 16:22:14 2019
tm1 = localtime(&t);
//依当前时间t获取时间数据到时间结构体tm1中
//时间结构体tm见文件开头
printf("111year == %d month == %d day == %d hour == %d\n",tm1->tm_year+1900,tm1->tm_mon+1,tm1->tm_mday,tm1->tm_hour);
tm2 = asctime(tm1);//获取依当前时间t得到的时间结构体数据\
然后将其转换成字符串函数返回其字符串存储的地址、、\
然后就可以直接打印其字符串得到时间数据
printf("%s\n",tm2);
char buf[100];
strftime(buf,100,"%y %m %d %S\n\0",tm1);
//size_t strftime(char *s, size_t max, \
const char *format, const struct tm *tm);
//将时间结构体tm1格式化输出到字符串数组中
printf("%s",buf);
}
return 0;
}
- stat
获取用户组信息
1.获取文件或目录的属性:
int stat(const char *path, struct stat *buf);
//EG stat(argv[1],&st)
//将文件信息存储到参数结构体buf中
int fstat(int fd, struct stat *buf);
int lstat(const char *path, struct stat *buf)
三个函数区别:
stat函数返回一个与此命名文件有关的信息结构
fstat函数获得已在描述符filedes上打开的文件的有关信息
lstat函数类似于stat,但是当命名的文件是一个符号连接时,
lstat返回该符号连接的有关信息,而不是由该符号连接引用的文件的信息
结构体
//struct stat {
// dev_t st_dev; /* ID of device containing file 文件id号*/
// ino_t st_ino; /* inode number 索引号*/
// mode_t st_mode; /* protection (权限)/
// 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; / blocksize for file system I/O 每一个块的大小*/
// blkcnt_t st_blocks; /* number of 512B blocks allocated 块个数 /
// time_t st_atime; / time of last access (最后一次访问时间)/
// time_t st_mtime; / time of last modification(最后一次修改时间) /
// time_t st_ctime; / time of last status change(最后一次修改的(依属性) /
//};
/
ls -l
st_mode st_nlink st_uid st_gid st_size st_mtime
文件类型 文件权限 硬链接数 用户 用户组名 文件大小 最后一次修改时间 文件名
1 . stat (路径,文件结构体地址) 成功返回0,失败返回-1并设置errno
2 .
获取用户信息
struct passwd *getpwuid(uid_t uid)
参数需要一个用户信息,返回一个用户信息结构体
struct passwd *getpwnam(const char *name)
参数需要一个用户信息,返回一个用户信息结构体
8、从stat下得文件属性的宏
The following flags are defined for the st_mode field:
S_IFMT 0170000 bit mask for the file type bit fields
S_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
S_ISUID 0004000 set UID bit
S_ISGID 0002000 set-group-ID bit (see below)
S_ISVTX 0001000 sticky bit (see below)
S_IRWXU 00700 mask for file owner permissions
S_IRUSR 00400 owner has read permission
S_IWUSR 00200 owner has write permission
S_IXUSR 00100 owner has execute permission
S_IRWXG 00070 mask for group permissions
S_IRGRP 00040 group has read permission
S_IWGRP 00020 group has write permission
S_IXGRP 00010 group has execute permission
S_IRWXO 00007 mask for permissions for others (not in group)
S_IROTH 00004 others have read permission
S_IWOTH 00002 others have write permission
S_IXOTH 00001 others have execute permission
使用例子
char *file_mode(mode_t m)
{
char *buf;
buf = malloc(10);
{
if (buf == NULL)
{
perror("malloc");
exit(1);
}
}
buf[0] = m & S_IRUSR ? 'r':'-';
buf[1] = m & S_IWUSR ? 'w':'-';
buf[2] = m & S_IXUSR ? 'x':'-';
buf[3] = m & S_IRGRP ? 'r':'-';
buf[4] = m & S_IWGRP ? 'w':'-';
buf[5] = m & S_IXGRP ? 'x':'-';
buf[6] = m & S_IROTH ? 'r':'-';
buf[7] = m & S_IWOTH ? 'w':'-';
buf[8] = m & S_IXOTH ? 'x':'-';
buf[9] = '\0';
return buf;
}
}
char file_type(mode_t m)
{
if(S_ISREG(m))//判断是否是普通文件
return '-';
if(S_ISDIR(m))
return 'd';
if(S_ISCHR(m))
return 'c';
if(S_ISBLK(m))
return 'b';
if(S_ISFIFO(m))
return 'p';
if(S_ISLNK(m))
return 'l';
if(S_ISSOCK(m))
return 's';
}
9、目录函数等
9.1. opendir
DIR *opendir(const char *name);
//打开一个目录,如果成功,返回一个目录指针,失败返回NULL,设置errno的值
9.2.closedir
9.3.readdir
struct dirent *readdir(DIR *dirp);
//读取目录,成功,返回一个目录文件结构体指针,失败返回NULL,设置errno的值
On Linux, the dirent structure is defined as follows:
struct dirent {
ino_t d_ino; /* inode number */
off_t d_off; /* offset to the next dirent */
unsigned short d_reclen; /* length of this record */
unsigned char d_type; /* type of file; not supported
by all file system types */
char d_name[256]; /* filename */
};
9.4. getopt
#include <unistd.h>
int getopt(int argc, char * const argv[],const char *optstring);
//参数一:主函数的argc,参数二:主函数的argv,参数三:命令行选项
//返回值:如果找到命令行选项,返回该字符,如果没有找到,返回,分析结束,返回-1
注意:使用命令行选项,需要加上-,而且是在选项之前,例如: ls -lai
eg:
void main (int argc,char *argv[])
{
int ret;
while(1)
{
ret = getopt(argc,argv,argv[1]);
if(ret == -1){
perror("getopt");
return;
}
switch (ret)
{
case 1:
perror("ret");
break;
case: 'l':
printf("%c\n",ret);
break;
case 'a':
printf("%c\n",ret);
break;
case 'i':
printf("%c\n",ret);
break;
default:
break;
}
}
}
9.5. glob
int glob(const char *pattern, int flags,int (*errfunc) (const char *epath, int eerrno),glob_t *pglob);
//参数一:路径 参数二:0 参数三:NULL 参数4: glob_t结构体
eg:
#include <stdio.h>
#include <glob.h>
void main (int argc,char *argv[])
{
glob_t glb;
glob("./*",0,NULL,&glb);
int i;
printf("%s\n",*glb.gl_pathv);
printf("%d\n",glb.gl_pathc);
for ( i = 0; i < glb.gl_pathc; i++)
{
printf("%s\n",glb.gl_pathv[i]);
}
}
编写在ubuntu中实现类shell指令的程序
现象:
1.实现查看文件属性
2.MYls -l实现查看文件夹文件
3.ls -a //ls -l程序删除一部分,只打印名字
4.ls -i //寻找inode号
5.ls -n //ls -l里面不用获取用户名和用户组名
6.ls -lian //getopt
code
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <pwd.h>
#include <grp.h>
#include <glob.h>
#include <time.h>
#include <dirent.h>
int select_opt(int argc,char* const * argv,char *argv1);
char file_type(mode_t m)
{
if(S_ISREG(m))
return '-';
if(S_ISDIR(m))
return 'd';
if(S_ISCHR(m))
return 'c';
if(S_ISBLK(m))
return 'b';
if(S_ISFIFO(m))
return 'p';
if(S_ISLNK(m))
return 'l';
if(S_ISSOCK(m))
return 's';
}
char *file_mode(mode_t m)
{
char *buf;
buf = (char*)malloc(10);
if (buf == NULL)
{
perror("malloc");
exit(1);
}
buf[0] = m & S_IRUSR ? 'r':'-';
buf[1] = m & S_IWUSR ? 'w':'-';
buf[2] = m & S_IXUSR ? 'x':'-';
buf[3] = m & S_IRGRP ? 'r':'-';
buf[4] = m & S_IWGRP ? 'w':'-';
buf[5] = m & S_IXGRP ? 'x':'-';
buf[6] = m & S_IROTH ? 'r':'-';
buf[7] = m & S_IWOTH ? 'w':'-';
buf[8] = m & S_IXOTH ? 'x':'-';
buf[9] = '\0';
return buf;
}
void display_f(struct stat st)
{
char mode = file_type(st.st_mode);
printf("%c",mode);
char *authority;
authority = (char*)malloc(sizeof(char)*10);
authority = file_mode(st.st_mode);
printf("%s ",authority);
printf("%d ",st.st_nlink);
struct passwd *pwd;
pwd = getpwuid(st.st_uid);
printf("%s ",pwd->pw_name);
struct group *grp;
grp = getgrgid(st.st_gid);
printf(" %s",grp->gr_name);
printf("%ld ",st.st_size);
struct tm *s;
s = localtime(&st.st_atime);
char tm1[100];
strftime(tm1,100,"%D %T",s);
printf("%s ",tm1);
}
void display_f1(struct stat st)
{
char mode = file_type(st.st_mode);
printf("%c",mode);
char *authority;
authority = (char*)malloc(sizeof(char)*10);
authority = file_mode(st.st_mode);
printf("%s ",authority);
printf("%d ",st.st_nlink);
/*
struct passwd *pwd;
pwd = getpwuid(st.st_uid);
printf("%s ",pwd->pw_name);
struct group *grp;
grp = getgrgid(st.st_gid);
printf(" %s",grp->gr_name);
*/
printf("%ld ",st.st_size);
struct tm *s;
s = localtime(&st.st_atime);
char tm1[100];
strftime(tm1,100,"%D %T",s);
printf("%s ",tm1);
}
int main(int argc,char *argv[])
{
glob_t glb;
char dir_name[100];
struct stat file_st;
struct dirent *d;//目录信息结构体指针
DIR *dir;
int i = 0;
char ch;
int sum = 0;
int stat1 = stat(argv[1],&file_st);
if (stat1<0)
{
perror("stat");
return -1;
}
ch = file_type(file_st.st_mode);
if(ch == 'd'){
if(argc>2)
sum =select_opt(argc,argv,argv[2]);
//printf("sum %d",sum);
dir = opendir(argv[1]);
if(dir == NULL)
{
perror("opendir");
return -2;
}
switch (sum)
{
case 205://-al
while (1)
{
d = readdir(dir);
if (d == NULL)
{
perror("read");
break;
}
sprintf(dir_name,"%s/%s",argv[1],d->d_name);
if(stat(dir_name,&file_st) < 0)//获取文件属性
{
perror("stat_dir_file");
return -4;
}
display_f(file_st);
printf(" %s\n",d->d_name);//8.获取文件名
}
break;
case 96 ://a
glob("./*",0,NULL,&glb);
for ( i = 0; i < glb.gl_pathc; i++)
{
printf("%s\n",glb.gl_pathv[i]);
}
break;
case 107://-l
while (1)
{
d = readdir(dir);
i++;
if (d == NULL)
{
perror("read");
break;
}
sprintf(dir_name,"%s/%s",argv[1],d->d_name);
if(stat(dir_name,&file_st) < 0)//获取文件属性
{
perror("stat_dir_file");
return -4;
}
if(i>2){
display_f(file_st);
printf(" %s\n",d->d_name);//8.获取文件名
}
}
break;
case 109://ls -n
while (1)
{
d = readdir(dir);
if (d == NULL)
{
perror("read");
break;
}
sprintf(dir_name,"%s/%s",argv[1],d->d_name);
if(stat(dir_name,&file_st) < 0)//获取文件属性
{
perror("stat_dir_file");
return -4;
}
display_f1(file_st);
printf(" %s\n",d->d_name);//8.获取文件名
}
break;
case 104:// -i
while (1)
{
d = readdir(dir);
if (d == NULL)
{
perror("read");
break;
}
sprintf(dir_name,"%s/%s",argv[1],d->d_name);
if(stat(dir_name,&file_st) < 0)//获取文件属性
{
perror("stat_dir_file");
return -4;
}
printf("node:%ld ",file_st.st_ino);
printf(" %s\n",d->d_name);//8.获取文件名
}
break;
case 311:
while (1)
{
d = readdir(dir);
if (d == NULL)
{
perror("read");
break;
}
sprintf(dir_name,"%s/%s",argv[1],d->d_name);
if(stat(dir_name,&file_st) < 0)//获取文件属性
{
perror("stat_dir_file");
return -4;
}
printf("node:%ld ",file_st.st_ino);
display_f(file_st);
printf(" %s\n",d->d_name);//8.获取文件名
}
break;
default:
break;
}
}
else
{
for(i=1;i<argc;i++)
{
if(stat(argv[i],&file_st) < 0)//获取文件属性
{
perror("stat");
return -4;
}
display_f(file_st);
printf(" %s\n",argv[i]);//8.获取文件名
}
}
//display_f(file_st);
return 0;
}
int select_opt(int argc,char* const * argv,char *argv1)
{
int i;
int *ret;
int sum = 0;
ret = (int*)malloc(sizeof(int)*4);
for ( i = 0; i < 4; i++)
{
ret[i] = getopt(argc,argv,argv1);
if(ret[0] == -1)
{
perror("getopt");
return;
}
switch (ret[i])
{
case 1:
perror("ret");
break;
case 'l':
printf("ret = %c\n",ret[i]);
break;
case 'a':
printf("ret = %c\n",ret[i]);
break;
case 'i':
printf("ret = %c\n",ret[i]);
break;
case 'n':
printf("ret = %c\n",ret[i]);
break;
default:
break;
}
}
for ( i = 0; i < 4; i++)
{
//printf("%d ",ret[i]);
sum+= ret[i];
}
puts("");
return sum;
}