1.文件的移动
rename系统调用可以用来修改文件名或文件的位置。
#include <stdio.h>
int rename(const char *oldpath, const char *newpath);
rename会将参数oldpath所指定的文件名称改为参数newpath所指定的文件名称。若newpath所指定的文件已存在,则原文件会被删除。执行成功返回0,失败返回-1。
2.文件的删除
文件的删除可以使用unlink系统调用,目录文件的删除可以使用rmdir系统调用,remove在内部封装了unlink和rmdir,当需要删除的是文件时,调用unlink,反之则调用rmdir。
#include <unistd.h>
int unlink(const char *pathname);
int rmdir(const char *pathname);
unlink系统调用从文件系统中删除一个文件,如果文件的链接数为0且没有进程打开这个文件,则文件被删除且其占用的磁盘空间被释放。如果文件的连接数虽为0,但是有进程打开这个文件则文件暂时不删除,直到所有打开该文件的进程都结束时文件才被删除。
参数pathname若指向一个符号链接,则该链接被删除,若参数pathname指向一个socket(套接字文件)、FIFO(命名管道)或设备文件时,该名字被删除,但已经打开这些文件的进程仍然可以使用这些特殊文件。函数执行成功返回0。失败返回-1。
如下的unlink应用:
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>
//自定义的错误处理函数
void my_err(const char * err_string, int line)
{
fprintf(stderr, "line:%d", line);
perror(err_string);
exit(1);
}
int main()
{
int fd;
char buf[32];
if((fd = open("temp", O_RDWR|O_CREAT|O_TRUNC)) < 0)
{
my_err("open", __LINE__);
}
if(unlink("temp") < 0 )
{
my_err("unlink", __LINE__);
}
printf("file unlinked\n");
if(write(fd, "temp", 5) < 0)
{
my_err("write", __LINE__);
}
if((lseek(fd, 0, SEEK_SET)) == -1)
{
my_err("lseek", __LINE__);
}
if(read(fd, buf, 5) < 0)
{
my_err("read", __LINE__);
}
printf("%s\n", buf);
return 0;
}
程序在执行过程中,在开始以可读可写的方式创建并打开了temp文件,由于进程并没有结束,所以unlink函数执行时暂时不会删除打开的temp文件,并且之后的temp文件读取是正常的,但是在程序执行结束之后temp却不存在,就是因为unlink在进程释放之后,将temp文件删除了。
3.目录的创建
目录的创建可以由mkdir系统调用来实现。
#include <sys/stat.h>
#include <sys/types.h>
int mkdir(const char *pathname, mode_t mode);
mkdir创建一个新的空目录。空目录中会自动创建.和..目录项,所创建的目录的存取权限由mode(mode & ~umask)指定。新目录的uid与创建目录的进程的uid一致。如果父目录设置了st_gid位,则创建的目录也设置 st_uid(目录被设置该位后,任何用户在此目录下创建的文件的组id与该目录的组id相同),函数执行成功返回0,失败返回-1。
4.获取当前目录
相对路径:不以斜线(根)开始的路径名
getcwd系统调用可以获取进程当前工作目录
#include <unistd.h>
char *getcwd(char *buf, size_t size);
char *getwd(char *buf);
char *get_current_dir_name(void);
getcwd会将当前的工作目录绝对路径复制到参数buf所指的内存空间,参数size为buf的空间大小。在调用此函数时,buf所指的空间要足够大,若工作目录绝对路径的字符串长度超过参数size大小,则返回NULL,若参数buf为NULL,getcwd()会根据参数size的大小自动分配内存,如果参数size也为0,则getcwd()会根据工作目录绝对路径的字符串长度来决定配置的内存大小,同时,进程在使用完此字符串之后利用free()释放此空间。执行成功则将结果复制到参数buf所指的内存空间,或是返回自动配置的字符串指针,失败返回NULL。
5.设置工作目录
使用chdir更改当前工作目录
#include <unistd.h>
int chdir(const char *path);
int fchdir(int fd);
chdir用来将当前工作目录改为由参数pathname指定的目录,fchdir用来将当前工作目录改为由参数fd(文件描述符)指定的目录。const char *path中的const含义是:在chdir函数实现代码中不允许path所指向的字符串的内容进行改变。函数执行成功返回0,有错误时返回-1。
利用chdir编写的cd命令如下:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<linux/limits.h>
//自定义错误处理函数
void my_err(const char * err_string, int line)
{
fprintf(stderr, "line:%d", line);
perror(err_string);
exit(1);
}
int main(int argc, char **argv)
{
char buf[PATH_MAX + 1];
if (argc < 2)
{
printf("my_cd <target path>\n");
exit(1);
}
if(chdir(argv[1]) < 0)
{
my_err("getcwd", __LINE__);
}
if(getcwd(buf, 512) < 0)
{
my_err("getcwd", __LINE__);
}
printf("%s\n", buf);
return 0;
}
程序先使用chdir系统调用将当前工作目录改变为命令行参数指定的目录,然后利用getcwd获取新的工作目录并打印出来,可以看出,虽然程序改变了该进程的工作目录,但并不能像cd命令一样切换目录,因为chdir函数调用只改变调用该函数的进程,对其他进程,如父进程的当前工作目录,则修改不了。
6.获取目录信息
- opendir:用来打开参数name指定的目录,并返回DIR*形态的目录流,类似与文件中的文件描述符。成功返回目录流,失败返回NULL。
- readdir:
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
readdir用来从参数dir所指向的目录中读取出目录项信息,返回一个struct dirent结构的指针
struct dirent
{
ino_t d_ino; /* inode number */
off_t d_off; /* not an offset; see NOTES */
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]; /* filename */
};
d_off是指目录文件开头至此目录进入点的位移,d_relen是指d_name的长度,d_name是指以NULL结尾的文件名。函数执行成功返回该目录下一个文件的信息,存储于dirent结构体中,如果调用opendir打开某个目录之后,第一次调用该函数,返回的是该目录下第一个文件的信息,第二次调用返回的是该目录下第二个文件的信息,依次类推,若该目录下已经没有文件可供读取(到达最后一个),则返回NULL。
3. closedir
#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);
closedir用来关闭dir参数指向的目录,执行成功返回0,有错误发生时返回-1。