1、虚拟地址空间
查看文件格式:file + 文件名
2、open函数
(1)open函数的形式
< 1> int open(const char * pathname , int flags , mode_t mode);
相关注释:
① const char * pathname:代表文件名
② int flags:代表执行命令(例如:只读、只写、读写等)
③ mode_t mode:代表设置文件权限
< 2> 相关打开文件命令
① O_RDONLY:只读
② O_WRONLY:只写
③ O_RDWR:即读又写
④ O_CREAT:自动创建指定新的文件
⑤ O_TRUNC:如果文件存在并且以可写方式打开时,使原文件内容清空为0
⑥ O_APPEND:以追加的方式打开文件
⑦ O_EXCL:和O_CREAT一起用,判断此文件是否存在,如果不存在,则输出错误信息并且创建该文件
< 3> 相关头文件
①
②
③
④
⑤
⑥
(2)有关代码
* *
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcnl.h>
#include <unistd.h>
int main ( )
{
int fd;
fd = open ( "hello.c" , O_RDWR) ;
if ( fd== - 1 )
{
perror ( "open file error" ) ;
exit ( 1 ) ;
}
int ret;
ret = close ( fd) ;
if ( ret== - 1 )
{
perror ( "close file error" ) ;
exit ( 1 ) ;
}
return 0 ;
}
* *
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcnl.h>
#include <unistd.h>
int main ( )
{
int fd;
fd = open ( "hello.c" , O_CREAT | O_RDWR, 0777 ) ;
if ( fd== - 1 )
{
perror ( "open file error" ) ;
exit ( 1 ) ;
}
int ret;
ret = close ( fd) ;
if ( ret== - 1 )
{
perror ( "close file error" ) ;
exit ( 1 ) ;
}
return 0 ;
}
* *
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcnl.h>
#include <unistd.h>
int main ( )
{
int fd;
fd = open ( "hello.c" , O_CREAT | O_EXCL | O_RDWR, 0777 ) ;
if ( fd== - 1 )
{
perror ( "open file error" ) ;
exit ( 1 ) ;
}
int ret;
ret = close ( fd) ;
if ( ret== - 1 )
{
perror ( "close file error" ) ;
exit ( 1 ) ;
}
return 0 ;
}
* *
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcnl.h>
#include <unistd.h>
int main ( )
{
int fd;
fd = open ( "hello.c" , O_TRUNC) ;
if ( fd== - 1 )
{
perror ( "open file error" ) ;
exit ( 1 ) ;
}
int ret;
ret = close ( fd) ;
if ( ret== - 1 )
{
perror ( "close file error" ) ;
exit ( 1 ) ;
}
return 0 ;
}
3、read和write函数
(1)read函数的返回值
1| 返回值为-1:说明文件读取失败
2| 返回值为0:说明文件已经读完了
3| 返回值为一个大于0的数:说明返回值为读取的字节数
(2)有关代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main ( )
{
int fd;
fd = open ( "hello.c" , O_RDONLY) ;
if ( fd == - 1 )
{
perror ( "open error" ) ;
exit ( 1 ) ;
}
int fd1;
fd1 = open ( "creat.c" , O_CREAT | O_WRONLY, 0777 ) ;
char a[ 2048 ] = { 0 } ;
int count;
count = read ( fd, a, sizeof ( a) ) ;
if ( count == - 1 )
{
perror ( "read error" ) ;
exit ( 1 ) ;
}
while ( count!= 0 )
{
int ret;
ret = write ( fd1, a, count) ;
printf ( "write bytes %d\n" , ret) ;
count = read ( fd, a, sizeof ( a) ) ;
}
close ( fd) ;
close ( fd1) ;
}
4、lseek函数
(1)函数结构
off_t lseek(int fd , off_t offset , int whence)
(2)有关参数
1| SEEK_SET:将指针指向文件头之后再增加offset个位移量
2| SEEK_CUR:以目前的光标位置往后增加offset个位移量
3| SEEK_END:将光标指向文件尾部后再增加offset个位移量
(3)相关代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main ( )
{
int fd;
fd = open ( "aa" , O_RDWR) ;
if ( fd == - 1 )
{
perror ( "open error" ) ;
exit ( 1 ) ;
}
int ret;
ret = lseek ( fd, 0 , SEEK_END ) ;
printf ( "The file length is :%d\n" , ret) ;
ret = lseek ( fd, 2000 , SEEK_END ) ;
printf ( "return value : %d\n" , ret) ;
write ( fd, "a" , 1 ) ;
close ( fd) ;
return 0 ;
}
5、stat函数
(1)函数形式
int stat(const char * path,struct stat * buf);
(2)包含的struct结构体
1| dev_t st_dev //文件的编号
2| ino_t st_ino //节点
3| mode_t st_mode //文件类型和存储权限
4| nlink_t st_nlink //连接到该文件的硬链接数目,刚刚建立的文件值为1
5| uid_t st_uid //用户ID
6| gid_t st_gid //组ID
7| dev_t st_rdev //(设备类型)如果此文件为设备文件,则为其设备编号
8| off_t st_size //文件字节数(文件大小)
9| blksize_t st_blksize //块的大小(文件系统的I/O缓冲区的大小)
10| blkcnt_t st_blocks //块数
11| time_t st_atime //最后一次访问时间
12| time_t st_mtime //最后一次修改时间
13| time_t st_ctime //最后一次改变世界(指的是属性)
(3)有关代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>
int main ( int argc, char * argv[ ] )
{
if ( argc< 2 )
{
printf ( "./a.out filename\n" ) ;
exit ( 1 ) ;
}
struct stat st;
int ret;
ret = stat ( argv[ 1 ] , & st) ;
if ( ret== - 1 )
{
perror ( "stat" ) ;
}
char perms[ 11 ] = { 0 } ;
switch ( st. st_mode & S_IFMT)
{
case S_IFLNK:
perms[ 0 ] = '1' ;
break ;
case S_IFDIR:
perms[ 0 ] = 'd' ;
break ;
case S_IFREG:
perms[ 0 ] = '-' ;
break ;
case S_IFBLK:
perms[ 0 ] = 'b' ;
break ;
case S_IFCHR:
perms[ 0 ] = 'c' ;
break ;
case S_IFSOCK:
perms[ 0 ] = 's' ;
break ;
}
perms[ 1 ] = ( st. st_mode & S_IRUSR) ? 'r' : '-' ;
perms[ 2 ] = ( st. st_mode & S_IWUSR) ? 'w' : '-' ;
perms[ 3 ] = ( st. st_mode & S_IXUSR) ? 'x' : '-' ;
perms[ 4 ] = ( st. st_mode & S_IRUSR) ? 'r' : '-' ;
perms[ 5 ] = ( st. st_mode & S_IWUSR) ? 'w' : '-' ;
perms[ 6 ] = ( st. st_mode & S_IXUSR) ? 'x' : '-' ;
perms[ 7 ] = ( st. st_mode & S_IRUSR) ? 'r' : '-' ;
perms[ 8 ] = ( st. st_mode & S_IWUSR) ? 'w' : '-' ;
perms[ 9 ] = ( st. st_mode & S_IXUSR) ? 'x' : '-' ;
int linkNum = st. st_nlink;
char * fileUser = getpwuid ( st. st_uid) -> pw_name;
char * fileGrp = getgrgid ( st. st_gid) -> gr_name;
int fileSize = ( int ) st. st_size;
char * time = ctime ( & st. st_mtime) ;
char mtime[ 512 ] = { 0 } ;
strncpy ( mtime, time, strlen ( time) - 1 ) ;
char buf[ 1024 ] ;
sprintf ( buf, "%s %d %s %s %d %s %s" , perms, linkNum, fileUser, fileGrp, fileSize, mtime, argv[ 1 ] ) ;
printf ( "%s\n" , buf) ;
return 0 ;
}
6、stat和lstat函数
(1)区别
1| stat:穿透函数(追踪函数) —————— 对于软链接 (例如:软链接的大小和原文件大小显示相同)
2| lstat:不穿透函数(不追踪函数) —————— 对于软链接 (例如:软链接的大小和原文件大小显示不相同)
(2)用法的代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main ( int argc, char * argv[ ] )
{
if ( argc < 2 )
{
printf ( "./a.out filename\n" ) ;
}
struct stat st;
int ret;
ret = lstat ( argv[ 1 ] , & st) ;
if ( ret == - 1 )
{
perror ( "stat error" ) ;
exit ( 1 ) ;
}
int size;
size = ( int ) st. st_size;
printf ( "file size is:%d\n" , size) ;
}
7、一些系统函数介绍
1| int access(const char *pathname,int mode)
参数:pathname(文件名)
mode(权限类别):
① R_OK:是否有读权限
② W_OK:是否有写权限
③ X_OK:是否有执行权限
④ F_OK:测试的该文件是否存在
2| int chmod(const char *path,mode_t mode)
3| int chown(const char *path,uid_t owner,gid_t group)
8、unlink创建临时文件
(1)函数形式
int unlink(const char* pathname);
(2)函数说明
1| unlink可以从文件系统里面删除一个指定文件
2| 如果返回值为-1,说明失败 如果返回值为0,说明成功
3| 在执行unlink函数之后依然可以读到文件中的内容,但是在整个程序执行完毕后文件会被删除
(3)有关代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
int main ( )
{
int fd;
fd = open ( "tempfile" , O_CREAT | O_RDWR, 0664 ) ;
if ( fd == - 1 )
{
perror ( "open error" ) ;
exit ( 1 ) ;
}
int ret;
ret = unlink ( "tempfile" ) ;
write ( fd, "hello\n" , 6 ) ;
lseek ( fd, 0 , SEEK_SET ) ;
char buf[ 100 ] = { 0 } ;
int p;
p = read ( fd, buf, sizeof ( buf) ) ;
write ( 1 , buf, p) ;
close ( fd) ;
return 0 ;
}
9、目录操作函数
(1)rename函数
1| 作用:文件重命名
2| 函数原型:int rename(const char *oldpath , const char *newpath);
(2)chdir函数
1| 作用:修改当前进程的路径
2| 函数原型:int chdir(const char *path);
(3)getcwd函数
1| 作用:获取当前进程工作的目录
2| 函数原型:char *getcwd(char *buf , size_t size);
(4)mkdir函数
1| 作用:创建目录
2| 注意点:创建的目录需要有执行权限,否则无法进入该目录
3| 函数原型:int mkdir(const char *pathname , mode_t mode);
(5)rmdir函数
1| 作用:删除一个空目录
2| 函数原型:int rmdir(const char *pathname);
10、opendir函数、readdir函数和closedir函数
(1)opendir函数
1| 作用:打开一个目录
2| 函数原型:DIR *opendir(const char *name);
3| 返回值:
< 1> DIR结构指针,该结构是一个内部结构,保存所打开的目录信息,作用类似于FILE结构
< 2> 函数出错返回NULL
(2)readdir函数
1| 作用:读目录
2| 函数原型:struct dirent *readdir(DIR *dirp);
3| 返回值:
< 1> 返回一条记录项
< 2> struct dirent
{
ino_t_d ino; //此目录进入点的inode(节点)
ff_t d_off; //目录文件开头到目录进入点的位移
signed short int d_reclen; //d_name的长度,不包含NULL字符
unsigned char d_type; //d_name所指的文件类型
har d_name[ 256] ; //文件名
} ;
4| d_type(文件类型):
DT_BLK:块设备 DT_CHR:字符设备 DT_DIR:目录
DT_LNK:软连接 DT_FIFO:管道 DT_REG:普通文件
DT_SOCK:套接字 DT_UNKNOWN:未知
11、递归实现读目录获取文件个数
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
int getfilenum ( char * root)
{
DIR* dir = NULL ;
dir = opendir ( root) ;
if ( dir == NULL )
{
perror ( "opendir error" ) ;
exit ( 1 ) ;
}
struct dirent* ptr = NULL ;
char path[ 2048 ] = { 0 } ;
int total = 0 ;
while ( ptr = readdir ( dir) != NULL )
{
if ( strcmp ( ptr-> d_name, "." ) == 0 || strcmp ( ptr-> d_name, ".." ) == 0 )
{
continue ;
}
if ( ptr-> d_type == DT_DIR)
{
sprintf ( path, "%s/%s" , root, ptr-> d_name) ;
total + = getfilenum ( path) ;
}
if ( ptr-> d_type == DT_REG)
{
total++ ;
}
}
}
int main ( int argc, char * argv[ ] )
{
if ( argc < 2 )
{
printf ( "./a.out dir\n" ) ;
exit ( 1 ) ;
}
int total = getfilenum ( argv[ 1 ] ) ;
printf ( "%s has file numbers %d\n" , argv[ 1 ] , total) ;
return 0 ;
}