文件和目录(二)
link,unlink,remove和rename函数
#include <unistd.h>
int link(const char *existingpath, const char * newpath) ;
返回:若成功则为0,若出错则为-1
- 此函数创建一个新目录项newpath,它引用现存文件existingpath。如若newpath已经存在,则返回出错。
- 这是一个原子操作。
- 只有超级用户进程可以创建指向一个目录的新连接。
为了删除一个现存的目录项,可以调用unlink函数。
#include <unistd.h>
int unlink(const char *pathname) ;
返回:若成功则为0,若出错则为-1
- 此函数删除目录项,并将由pathname所引用的文件的连接计数减1。如果该文件还有其他连接,则仍可通过其他连接存取该文件的数据。如果出错,则不对该文件作任何更改。
- 只有当连接计数达到 0时,该文件的内容才可被删除。另一个条件也阻止删除文件的内容——只要有进程打开了该文件,其内容也不能删除。关闭一个文件时,内核首先检查使该文件打开的进程计数。如果该计数达到0,然后内核检查其连接计数,如果这也是 0,那么就删除该文件的内容。
因此可以使用unlink来创建临时文件,先open再unlink,那么在进程结束时,临时文件就会自动删除,即使程序崩溃临时文件也不会残留下来。
- 如果pathname时一个符号连接,那么unlink涉及的是符号连接而不是由该连接所引用的文件。
#include <stdio.h>
int remove(const char *pathname);
返回:若成功则为0,若出错则为-1
remove函数解除对一个文件或目录的连接。对于文件, remove的功能与unlink相同。对于目录,remove的功能与rmdir相同。
文件或目录用rename更名
#include <stdio.h>
int rename(const char *oldname, const char *newname) ;
返回:若成功则为0,若出错则为-1
符号连接
- 符号连接是对一个文件的间接指针。
- 调用函数时需注意该函数时对符号连接调用还是对指向的文件调用。
symlink和readlink函数
symlink函数创建一个符号连接。
#include <unistd.h>
int symlink(const char *actualpath, const char *sympath) ;
返回:若成功则为0,若出错则为-1
该函数创建了一个指向actualpath的新目录项sympath。
#include <unistd.h>
int readlink(const char *pathname, char *buf, int bufsize) ;
返回:若成功则为读的字节数,若出错则为- 1
因为open不能直接打开符号连接,所以该函数打开连接本身,并读取名字,此函数组合了open read close的所以操作。
文件的时间
i节点状态的最后更改时间是指存取许可位,连接数,用户ID的修改。
utime函数
一个文件的存取和修改时间可以用utime函数更改。
#include <sys/types.h>
#include <utime.h>
int utime(const char *pathname, const struct utimbuf * times) ;
返回:若成功则为0,若出错则为-1
utimbuf结构体结构如下
struct utimbuf {
time_t actime; /*access time*/
time_t modtime; /*modification time*/
}
该函数的操作取决于times是否为NULL
- 如果times为NULL,则将存取时间和修改时间设置为当前时间。此操作需满足两个条件之一:(a)进程的有效用户ID必须等于该文件的所有者ID,(b)进程对该文件必须具有写许可权。
- 如果times不为NULL,则将存取时间和修改时间设置为times。
- 我们不能更改i节点状态时间的值。
mkdir和rmdir函数
#include <sys/types.h>
#include <sys/stat.h>
int mkdir(const char *pathname, mode_t mode);
返回:若成功则为0,若出错则为-1
创建一个新的目录。
#include <unistd.h>
int rmdir(const char *pathname);
返回:若成功则为0,若出错则为- 1
删除一个空目录。
读目录
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *pathname) ;
返回:若成功则为指针,若出错则为NULL
struct dirent *readdir(DIR *dp) ;
返回:若成功则为指针,若在目录尾或出错则为NULL
void rewinddir(DIR *dp) ;
int closedir(DIR *dp) ;
返回:若成功则为0,若出错则为-1
DIR类似于FILE结构,由opendir返回的指向DIR结构的指针由另外三个函数使用。opendir执行初始化操作,使第一个readdir读目录中的第一个目录项。目录中各目录项的顺序与实现有关。它们通常并不按字母顺序排列。
chdir, fchdir 和getcwd函数
#include <unistd.h>
int chdir(const char *pathname) ;
int fchdir(int filedes) ;
两个函数的返回:若成功则为 0,若出错则为-1
可以分别用pathname或打开文件描述符来指定新的当前工作目录。
该函数只影响该进程的当前工作目录,不影响其他进程。
#include<unistd.h>
char *getcwd(char *buf, size_t size);
返回:若成功则为buf, 若出错则为NULL
该函数将绝对路径存到buf中,size需足够大来保存绝对路径。
特殊设备文件
看不懂,将来再补
sync和fsync函数
#include <unistd.h>
void sync(void);
int fsync(int filedes) ;
返回:若成功则为0,若出错则为-1
sync只是将所有修改过的块的缓存排入写队列,然后就返回,它并不等待实际I/O操作结束。
fsync将指定文件描述符,等待I/O结束再返回。