c非标准库参考5-文件与目录操作

chdir(改变当前的工作目录)

#include <unistd.h>
int chdir(const char *path);

chdir()用来将当前的工作目录改变成以参数path所指的目录。
执行成功则返回0,失败返回-1,errno为错误代码。

chmod(改变文件的权限)

#include <sys/types.h>
#include <sys/stat.h>
int chmod(const char *path, mode_t mode);

chmod()会依参数mode来更改参数path指定文件的权限。参数mode有下列数种组合:
S_ISUID 04000 文件的(set user-id on execution)位
S_ISGID 02000 文件的(set group-id on execution)位
S_ISVTX 01000 文件的sticky位
S_IRUSR(S_IREAD) 00400 文件所有者具可读取权限
S_IWUSR(S_IWRITE)00200 文件所有者具可写入权限
S_IXUSR(S_IEXEC) 00100 文件所有者具可执行权限
S_IRGRP 00040 用户组具可读取权限
S_IWGRP 00020 用户组具可写入权限
S_IXGRP 00010 用户组具可执行权限
S_IROTH 00004 其他用户具可读取权限
S_IWOTH 00002 其他用户具可写入权限
S_IXOTH 00001 其他用户具可执行权限

只有该文件的所有者或有效用户识别码为0,才可以修改该文件权限。基于系统安全,如果欲将数据写入一执行文件,而该执行文件具有S_ISUID 或S_ISGID 权限,则这两个位会被清除。

权限改变成功返回0,失败返回-1,错误原因存于errno。

chown(改变文件的所有者)

#include <sys/types.h>
#include <unistd.h>
int chown(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。

stat(取得文件状态)

#include <sys/stat.h>
#include <unistd.h>
int stat(const char *file_name, struct stat *buf);

stat()用来将参数file_name所指的文件状态,复制到参数buf所指的结构中。下面是struct stat内各参数的说明:

struct stat
{
    dev_t st_dev; /*device*/
    ino_t st_ino; /*inode*/
    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 type */
    off_t st_size; /*total size, in bytes*/
    unsigned long st_blksize; /*blocksize for filesystem I/O*/
    unsigned long st_blocks; /*number of blocks allocated*/
    time_t st_atime; /*time of lastaccess*/
    time_t st_mtime; /*time of last modification,修改文件内容*/
    time_t st_ctime; /*time of last change,改变文件属性*/
};

st_dev 文件的设备编号
st_ino 文件的i-node
st_mode 文件的类型和存取的权限
st_nlink 连到该文件的硬连接数目
st_uid 文件所有者的用户识别码
st_gid 文件所有者的组识别码
st_rdev 若此文件为装置设备文件,则为其设备编号
st_size 文件大小,以字节计算
st_blksize 文件系统的I/O 缓冲区大小。
st_blcoks 占用文件区块的个数,每一区块大小为512 个字节
st_atime 文件最近一次被存取或被执行的时间,一般只有在用mknod、utime、read、write与tructate时改变。
st_mtime 文件最后一次被修改的时间,一般只有在用mknod、utime和write时才会改变
st_ctime i-node最近一次被更改的时间,此参数会在文件所有者、组、权限被更改时更新

st_mode定义了下列数种情况:
S_IFMT 0170000 文件类型的位遮罩
S_IFSOCK 0140000 scoket
S_IFLNK 0120000 符号连接
S_IFREG 0100000 一般文件
S_IFBLK 0060000 区块装置
S_IFDIR 0040000 目录
S_IFCHR 0020000 字符装置
S_IFIFO 0010000 先进先出
S_ISUID 04000 文件的(set user-id on execution)位
S_ISGID 02000 文件的(set group-id on execution)位
S_ISVTX 01000 文件的sticky位
S_IRUSR(S_IREAD) 00400 文件所有者具可读取权限
S_IWUSR(S_IWRITE)00200 文件所有者具可写入权限
S_IXUSR(S_IEXEC) 00100 文件所有者具可执行权限
S_IRGRP 00040 用户组具可读取权限
S_IWGRP 00020 用户组具可写入权限
S_IXGRP 00010 用户组具可执行权限
S_IROTH 00004 其他用户具可读取权限
S_IWOTH 00002 其他用户具可写入权限
S_IXOTH 00001 其他用户具可执行权限

POSIX定义了检查这些类型的宏定义:
S_ISLNK(st_mode) 判断是否为符号连接
S_ISREG(st_mode) 是否为一般文件
S_ISDIR(st_mode) 是否为目录
S_ISCHR(st_mode) 是否为字符装置文件
S_ISBLK(st_mode) 是否为先进先出
S_ISSOCK(st_mode) 是否为socket

执行成功则返回0,失败返回-1,错误代码存于errno。

truncate(改变文件大小)

#include <unistd.h>
int truncate(const char *path, off_t length);

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

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

fchdir(改变当前的工作目录)

#include <unistd.h>
int fchdir(int fd);

fchdir()用来将当前的工作目录改变成以参数fd所指的文件描述词。
行成功则返回0,失败返回-1,errno为错误代码。

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
main()
{
int fd;
fd = open("/tmp",O_RDONLY);
fchdir(fd);
printf("current working directory:%s\n",getcwd(NULL,0));
close(fd);
}

current working directory:/tmp

fchmod(改变文件的权限)

#include <sys/types.h>
#include <sys/stat.h>
int fchmod(int fd, mode_t mode);

fchown(改变文件的所有者)

#include <sys/types.h>
#include <unistd.h>
int fchown(int fd, uid_t owner, gid_t group);

fchown()会将参数fd指定文件的所有者变更为参数owner代表的用户,而将该文件的组变更为参数group组。

ftruncate(改变文件大小)

#include <unistd.h>
int ftruncate(int fd, off_t length);

ftruncate()会将参数fd指定的文件大小改为参数length指定的大小。参数fd为已打开的文件描述词,而且必须是以写入模式打开的文件。如果原来的文件大小比参数length大,则超过的部分会被删去。
执行成功则返回0,失败返回-1,错误原因存于errno。
EBADF 参数fd文件描述词为无效的或该文件已关闭。
EINVAL 参数fd 为一socket并非文件,或是该文件并非以写入模式打开。

fstat(由文件描述词取得文件状态)

#include <sys/stat.h>
#include <unistd.h>
int fstat(int fd, struct stat *buf);

fstat()与stat()作用完全相同,不同处在于传入的参数为已打开的文件描述词。

lstat(由文件描述词取得文件状态)

#include <sys/stat.h>
#include<unistd.h>
int lstat(const char *file_name, struct stat *buf);

lstat()与stat()作用完全相同,都是取得参数file_name所指的文件状态,其差别在于,当文件为符号连接时,lstat()会返回该link本身的状态。
执行成功则返回0,失败返回-1,错误代码存于errno。


link(建立文件连接)

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

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

成功则返回0,失败返回-1,错误原因存于errno。
link()所建立的硬连接无法跨越不同文件系统,如果需要请改用symlink()。

unlink(删除文件)

#include <unistd.h>
int unlink(const char *pathname);

unlink()会删除参数pathname指定的文件。如果该文件名为最后连接点,但有其他进程打开了此文件,则在所有关于此文件的文件描述词皆关闭后才会删除。如果参数pathname为一符号连接,则此连接会被删除。

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

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。


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()来释放此空间。

执行成功则将结果复制到参数buf所指的内存空间,或是返回自动配置的字符串指针。失败返回NULL,错误代码存于errno。

umask(设置建立新文件时的权限遮罩)

#include <sys/types.h>
#include <sys/stat.h>
mode_t umask(mode_t mask);

umask()会将系统umask值设成参数mask&0777后的值,然后将先前的umask值返回。在使用open()建立新文件时,该参数mode并非真正建立文件的权限,而是(mode&~umask)的权限值。例如,在建立文件时指定文件权限为0666,通常umask值默认为022,则该文件的真正权限则为0666&~022=0644,也就是rw-r–r–。此调用不会有错误值返回。返回值为原先系统的umask值。

utime(修改文件的访问时间和修改时间)

#include <sys/types.h>
#include <utime.h>
int utime(const char *filename, struct utimbuf *buf);

结构utimbuf定义如下:
struct utimbuf{
time_t actime;
time_t modtime;
};
如果参数buf为NULL,则该文件的访问间和修改时间全部会设为目前时间。
执行成功则返回0,失败返回-1,错误代码存于errno。

utimes(修改文件的访问时间和修改时间)

#include <sys/types.h>
#include <utime.h>
int utimes(char *filename, struct timeval *tvp);

结构timeval定义如下:
struct timeval {
long tv_sec;
long tv_usec;
};
参数tvp指向两个timeval结构空间,和utime()使用的utimebuf结构比较,tvp[0].tc_sec则为utimbuf.actime,tvp[1].tv_sec为utimbuf.modtime。
执行成功则返回0。失败返回-1,错误代码存于errno。

remove(删除文件)

#include <stdio.h>
int remove(const char *pathname);

remove()会删除参数pathname指定的文件。如果参数pathname为一文件,则调用unlink()处理,若参数pathname为一目录,则调用rmdir()来处理。
成功则返回0,失败则返回-1,错误原因存于errno。

rename(更改文件名称或位置)

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

rename()会将参数oldpath所指定的文件名称改为参数newpath所指的文件名称。若newpath所指定的文件已存在,则会被删除。

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

access(判断是否具有存取文件的权限)

#include <unistd.h>
int access(const char *pathname, int mode);

access()会检查是否可以读/写某一已存在的文件。参数mode有几种情况组合,R_OK,W_OK,X_OK和F_OK。R_OK,W_OK与X_OK用来检查文件是否具有读取、写入和执行的权限,F_OK则是用来判断该文件是否存在。只是检查该文件的rwx状态。

若所有欲查核的权限都通过了检查则返回0值,表示成功,只要有一权限被禁止则返回-1。


opendir(打开目录)

#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);

opendir()用来打开参数name指定的目录,并返回DIR*形态的目录流,接下来对目录的读取和搜索都要使用此返回值。
成功则返回DIR* 型态的目录流,打开失败则返回NULL。

closedir(关闭目录)

#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dir);

closedir()关闭参数dir所指的目录流。
关闭成功则返回0,失败返回-1,错误原因存于errno 中。

readdir(读取目录)

#include <sys/types.h>
#include <dirent.h>
struct dirent *readdir(DIR *dir);

readdir()返回参数dir目录流的下个目录进入点。结构dirent定义如下:

struct dirent
{
    __ino_t d_ino;//此目录进入点的inode
    __off_t d_off;
    unsigned short int d_reclen;
    unsigned char d_type;
    char d_name[256];//文件名
};

成功则返回下个目录进入点,有错误发生或读取到目录文件尾则返回NULL。

telldir(取得目录流的读取位置)

#include <dirent.h>
long int telldir(DIR *dir);

telldir()返回参数dir目录流目前的读取位置。此返回值代表距离目录文件开头的偏移量。
返回下个读取位置,有错误发生时返回-1。

#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
int main()
{
    DIR *dir;
    struct dirent *ptr;
    int offset;
    dir = opendir("/etc/rc.d");
    while((ptr=readdir(dir)) != NULL)
    {
        offset = telldir(dir);
        printf("name is %s osset is %ld\n", ptr->d_name, offset);
    }
    closedir(dir);
    return 0;
}

name is rc5.d osset is 201799034
name is init.d osset is 467150402
name is rc3.d osset is 643982894
name is rc2.d osset is 685354372
name is rc osset is 857290140
name is rc0.d osset is 869656362
name is .. osset is 980638356
name is rc.local osset is 983341700
name is rc.sysinit osset is 1030115943
name is rc6.d osset is 1341885257
name is rc4.d osset is 1699883001
name is rc1.d osset is 1944399196
name is . osset is 2147483647

seekdir(设置下回读取目录的位置)

#include <dirent.h>
void seekdir(DIR *dir, long pos);

seekdir()用来设置参数dir目录流目前的读取位置,在调用readdir()时便从此新位置开始读取。

rewinddir(重设读取目录的位置为开头位置)

#include <sys/types.h>
#include <dirent.h>
void rewinddir(DIR *dir);

rewinddir()用来设置参数dir目录流目前的读取位置为原来开头的读取位置。

scandir

#include  <dirent.h>
int scandir(const char *dir, struct dirent ***namelist, int (*selector)(const struct dirent *), int (*cmp)(const void *, const void *));

scandir()会扫描参数dir指定的目录流,经由参数select指定的函数来挑选目录结构至参数namelist数组中,最后再调用参数cmp指定的函数来排序namelist数组中的目录数据。每次从目录文件中读取一个目录结构后便将此结构传给参数select所指的函数, select函数若不想要将此目录结构复制到namelist数组就返回0,若select为空指针则代表选择所有的目录结构。scandir()会调用qsort()来排序数据,参数cmp则为qsort()的参数,若是要排列目录名称字母则可使用alphasort()。

成功则返回复制到namelist数组中的数据结构数目,有错误发生则返回-1。

alphasort(依字母顺序排序目录结构)

#include<dirent.h>
int alphasort(const struct dirent **a, const struct dirent **b);
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
int main()
{
struct dirent **namelist;
int i,total;
total = scandir("/",&namelist,0,alphasort);
if(total<0)
perror("scandir");
else{
for(i=0;i<total;i++)
{
    printf("%s\n",namelist[i]->d_name);
    free(namelist[i]);
}
printf("total = %d\n",total);
free(namelist);
}
}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REaDME.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值