您的位置:首页 > 其它

(十七)文件操作——其余相关函数的介绍、以及递归输出目录中的文件列表

2017-01-01 21:02 741 查看

chown

#include <unistd.h>

int chown(const char *path, uid_t owner, gid_t group);
int fchown(int fd, uid_t owner, gid_t group);
int lchown(const char *path, uid_t owner, gid_t group);


函数说明:chown()会将参数path 指定文件的所有者变更为参数owner 代表的用户,而将该文件的组变更为参数group 组。如果参数owner 或group 为-1,对应的所有者或组不会有所改变。root 与文件所有者皆可改变文件组,但所有者必须是参数group 组的成员。当root 用chown()改变文件所有者或组时,该文件若具有S_ISUID或S_ISGID 权限,则会清除此权限位,此外如果具有S_ISGID 权限但不具S_IXGRP 位,则该文件会被强制锁定,文件模式会保留。

返回值:成功则返回0, 失败返回-1, 错误原因存于errno

utime

#include <sys/types.h>
#include <utime.h>

int utime(const char * filename, struct utimbuf * buf);


函数说明:utime()用来修改参数filename 文件所属的inode 存取时间。结构utimbuf 定义如下:

struct utimbuf

{

time_t actime;

time_t modtime;

};

返回值:如果参数buf 为空指针(NULL), 则该文件的存取时间和更改时间全部会设为目前时间.。执行成功则返回0,失败返回-1,错误代码存于errno。

truncate

#include <unistd.h>
#include <sys/types.h>

int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);


函数说明:truncate()会将参数path 指定的文件大小改为参数length 指定的大小. 如果原来的文件大小比参数length 大, 则超过的部分会被删去.

返回值:执行成功则返回0, 失败返回-1, 错误原因存于errno.

link

#include <unistd.h>

int link(const char *oldpath, const char *newpath);


函数说明:link()以参数newpath 指定的名称来建立一个新的连接(硬连接)到参数oldpath 所指定的已存在文件. 如果参数newpath 指定的名称为一已存在的文件则不会建立连接.

返回值:成功则返回0, 失败返回-1, 错误原因存于errno.

注:

创建一个硬链接

当rm删除文件时,只是删除了目录下的记录项和把inode硬链接计数减1,当硬链接计数减为0时,才会真正的删除文件。

链接通常要求位于同一文件系统中,POSIX允许夸文件系统

符号链接没有文件系统限制

通常不允许创建目录的硬链接,某些unix系统下超级用户可以创建目录的硬链

创建目录项以及增加硬链接计数应当是一个原子操作

symlink

link()所建立的硬连接无法跨越不同文件系统, 如果需要则改用symlink()

#include <unistd.h>

int symlink(const char * oldpath, const char * newpath);


函数说明:symlink()以参数newpath 指定的名称来建立一个新的连接(符号连接)到参数oldpath 所指定的已存在文件. 参数oldpath 指定的文件不一定要存在, 如果参数newpath 指定的名称为一已存在的文件则不会建立连接.

返回值:成功则返回0, 失败返回-1, 错误原因存于errno.

readlink

#include <unistd.h>

int readlink(const char * path, char * buf, size_t bufsiz);


函数说明:读符号链接所指向的文件名字,不读文件内容,readlink()会将参数path 的符号连接内容存到参数buf 所指的内存空间, 返回的内容不是以NULL作字符串结尾, 但会将字符串的字符数返回. 若参数bufsiz 小于符号连接的内容长度, 过长的内容会被截断.

返回值:执行成功则传符号连接所指的文件路径字符串, 失败则返回-1, 错误代码存于errno

unlink

#include <unistd.h>

int unlink(const char * pathname);


函数说明:unlink()会删除参数pathname 指定的文件。

如果是符号链接,删除符号链接

如果是硬链接,硬链接数减1,当减为0时,释放数据块和inode

如果文件硬链接数为0,但有进程已打开该文件,并持有文件描述符,则等该进程关闭该文件时,kernel才真正去删除该文件

利用该特性创建临时文件,先open或creat创建一个文件,马上unlink此文件

rename

#include <stdio.h>
int rename(const char *oldpath, const char *newpath);


函数说明:重命名文件、改变文件路径或更改目录名称

参数:oldname为旧文件名,newname为新文件名。

返回值:修改文件名成功则返回0,否则返回-1。

重命名文件:

如果newname指定的文件存在,则会被删除。

如果newname与oldname不在一个目录下,则相当于移动文件。

重命名目录:

如果oldname和oldname都为目录,则重命名目录。<
c225
/li>
如果newname指定的目录存在且为空目录,则先将newname删除。

对于newname和oldname两个目录,调用进程必须有写权限。

重命名目录时,newname不能包含oldname作为其路径前缀。例如,不能将/usr更名为/usr/foo/testdir,因为老名字( /usr/foo)是新名字的路径前缀,因而不能将其删除。

getcwd

#include <unistd.h>

char * getcwd(char * buf, size_t size);


函数说明:getcwd()会将当前的工作目录绝对路径复制到参数buf 所指的内存空间,参数size 为buf 的空间大小。

在调用此函数时,buf 所指的内存空间要足够大。若工作目录绝对路径的字符串长度超过参数size 大小,则返回NULL,errno 的值则为ERANGE。

倘若参数buf 为NULL,getcwd()会依参数size 的大小自动配置内存(使用malloc()),如果参数size 也为0,则getcwd()会依工作目录绝对路径的字符串程度来决定所配置的内存大小,进程可以在使用完次字符串后利用free()来释放此空间。

递归列出目录中的文件列表

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <stdio.h>
#include <string.h>

#define MAX_PATH 1024

/* dirwalk: apply fcn to all files in dir */
//第二个参数定义了一个名为fcn的函数指针,指向有一个参数的且返回值为空的函数
void dirwalk(char *dir, void (*fcn)(char *))
{
char name[MAX_PATH];
struct dirent *dp;//定义记录项指针
DIR *dfd;//定义目录项指针

//如果该目录打开失败
if ((dfd = opendir(dir)) == NULL) {
fprintf(stderr, "dirwalk: can't open %s\n", dir);
return;
}

/*
*逐个获取记录项直到最后
*当记录项没有到最后的时候调用readdir返回该记录项指针
*当记录项到最后的时候调用readdir返回NULL
*每调用一次readdir目录指针中的记录项指针向下移动一次
*/
while ((dp = readdir(dfd)) != NULL)
{
if (strcmp(dp->d_name, ".") == 0
|| strcmp(dp->d_name, "..") == 0)
continue; /* 跳过.和..这两个目录  skip self and parent */

if (strlen(dir)+strlen(dp->d_name)+2 > sizeof(name))
fprintf(stderr, "dirwalk: name %s %s too long\n",
dir, dp->d_name);//如果目录和其路径过长则打印出错信息
else
{   //打印该路径及其目录名
sprintf(name, "%s/%s", dir, dp->d_name);
(*fcn)(name);//将该目录名传递回去重新调用fsize函数
}
}
closedir(dfd);
}
/* fsize: print the size and name of file "name" */
void fsize(char *name)
{
//获取该文件信息
struct stat stbuf;
if (stat(name, &stbuf) == -1) {
fprintf(stderr, "fsize: can't access %s\n", name);
return;
}

/*
*该文件的st_mode和类型掩码相与即可获取该文件的类型
*判断是否为目录文件,如果是则调用dirwalk函数
*并将该目录名和该fsize函数传递过去(函数作为函数参数,即回调函数)
*/
if ((stbuf.st_mode & S_IFMT) == S_IFDIR)
dirwalk(name, fsize);

//如果不是目录则打印文件大小和名字
printf("%8ld %s\n", stbuf.st_size, name);
}
int main(int argc, char **argv)
{
/*
*如果只有./app一个参数的时候则打开.目录,即当前目录
*若有多个参数则逐个打开所有参数中的目录
*以上的打开即调用fsize函数
*/
if (argc == 1) /* default: current directory */
fsize(".");
else
while (--argc > 0)
fsize(*++argv);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: