[APUE]文件和目录(中)

一、link、unlink、remove和rename

  1. 一个文件可以有多个目录项指向其i节点。使用link函数可以创建一个指向现存文件连接
#include <unistd.h>
int link(const char *existingpath, const char *newpath);
返回值:成功为0,出错为-1

该函数创建一个新目录项newpath,指向现存文件existingpath,如果newpath已存在则返回出错。

  1. 为了删除一个现存的目录项,可以调用unlnk函数。
#include <unistd.h>
int unlink(const char *pathname);
返回值:成功为0,出错为-1

此函数删除目录项,并将pathname引用的文件的连接计数-1。 只有当连接计数达到0时该文件的内容才能被删除,如果有进程打开了该文件其内容也不能删除。关闭一个文件时内核首先检查使该文件打开的进程计数,如果该计数为0再检查连接计数,如果为0那就删除该文件。

  1. 使用remove函数可以解除对一个文件或目录的连接,对于文件,remove的功能与unlink相同。对于目录,remove的功能与rmdir相同。
#include <stdio.h>
int remove(const char *pathname);
  1. 文件或目录用rename函数重命名
#include <stdio.h>
int rename(const char *oldname, const char *newname);

根据oldname是目录还是文件有两种情况:

  (1) 如果oldname是一个文件则为该文件更名。在这种情况下,如果newname已存在,则它不能引用一个目录。如果newname已存在,而且不是一个目录,则先将该目录项(这里不是目录!)删除然后将oldname更名为newname。对包含oldname和newname的目录,调用进程必须具有写权限,因为将更改这两个目录。

  (2) 如果oldname说明一个目录,那么为该目录重命名。如果newname已存在,则它必须引用一个目录,而且该目录应当是空目录。如果newname存在而且是一个空目录,则先将其删除,然后将oldname更名为newname。不能将/usr/foo更名为/usr/foo/dir,因为oldname /usr/foo是newname /usr/foo/dir的前缀,无法删除。可以将/tmp/orlion/b/(假如该文件夹下有个c文件)更名为/tmp/orlion_1/,修改完成后可以看到orlion_1文件夹下有个c文件。

  (3) 如果oldname和newname引用同一个文件,则不做任何修改而返回成功。 如果newname已存在,则进程必须需要对其有写权限(如同删除一样)。另外进程将删除oldname目录项,并可能要创建newname目录项,所以它需要对包含oldname及包含newname的目录具有写和执行权。

二、符号连接

符号链接是对一个文件的间接指针。rmdir函数如果path是符号链接则返回出错,所以下表没有列出各个函数对符号连接的处理如下:

  

三、symlink和readlink函数

symlink函数创建一个符号连接。

#include <unistd.h>
int symlink(const char *actualpath, const char *sympath);

在创建符号连接时并不要求actualpath存在。并且不要求actualpath和sympath在同一文件系统中而硬连接要求。 因为open函数会跟随符号连接(即实际打开的是符号连接连接的文件),所以需要一种方法打开该连接本身,readlink提供了这种功能。

#include <unistd.h>
int readlink(const char *pathname, char *buf, int bufsize);

此函数组合了open,read和close的所有操作。 如果成功则返回读入buf的字节数如果失败则返回-1。在buf返回的文件链接的内容不以null字符终止。

四、文件的时间

每个文件有三个时间段,如下图:

  

下表是各种函数对这三个时间的作用。 目录是包含目录项(文件名和相关的i节点)的文件,增加、删除或修改目录项会影响到与其所在目录相关的三个时间。例如,创建一个新文件会影响到包含该文件的目录(因为目录实质上是包含该文件的文件),也影响新文件的i节点,但是读或写只影响该文件的i节点,而对父目录则无影响。

  

五、utime函数

一个文件的存取和修改时间可以用utime函数更改。

#include <sys/types.h>
int utime(const char *pathname, const struct utimbuf *times);
返回值:成功0,失败-1.

此函数所使用的结构是:

struct utimbuf {
  time_t actime; /* access time */
  time_t modtime; /* modification time */
}

结构体中的两个时间都是unix时间戳。

此函数的操作以及执行它所要求的优先权取消于times参数是否是NULL。

  (1) 如果times是一个空指针,则存取时间和修改时间两者都设置为当前时间。为了执行次操作必须满足两条件之一(a)进程的有效用户ID必须等于该文件的所有者ID,(b)进程对该文件必须具有写许可权。

  (2) 如果times是非空指针,则存取时间和修改时间被设置为times所指向的结构体中的值。此时,进程的有效用户ID必须等于该文件的所有者或者进程是一个root进程。对文件只有写权限是不够的。

不能修改文件的状态时间st_ctime,当调用utime时,此字段被自动更新。

时间: 2024-10-03 10:13:40

[APUE]文件和目录(中)的相关文章

搜索文件或目录中包含字符串的文件 java小程序

package com.ruishenh.spring.test; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Enumeration; import java.

[APUE]文件和目录

一.APUE这一章中的各种晦涩名词 我在读这一章时遇到了各种ID,根据名字完全不清楚什么意思,幸好看到了这篇文章,http://blog.csdn.net/ccjjnn19890720/article/details/6990656,总结一下 每一个进程其实对应了6个以上的ID,它们分别是:实际用户ID.实际组ID(我们实际上是谁,执行这个程序的用户和组),有效用户ID.有效组ID.附加组ID(用于文件访问权限检查),保存设置用户ID,保存设置组ID(由exec函数保存) 实际用户ID/实际组I

APUE: 文件和目录相关的系统调用

Tips:下面的总结是参考APUE(unix环境高级编程)这本书,在linux(ubuntu)上的实现. Linux系统的调用结构: 最上层:应用程序+shell命令(外部命令在coreutils中实现,内部命令在bash中实现) 中间层:linux下的库函数(gnu的c标准库在glibc中实现) 最底层:linux内核(163个linux系统调用接口+内核子系统(驱动)) 系统调用是linux内核和外部的唯一接口. unix的标准主要有两个: posix标准:可移植操作系统接口,IEEE.IS

linux复制指定目录下的全部文件到另一个目录中

linux复制指定目录下的全部文件到另一个目录中复制指定目录下的全部文件到另一个目录中文件及目录的复制是经常要用到的.linux下进行复制的命令为cp.假设复制源目录 为 dir1 ,目标目录为dir2.怎样才能将dir1下所有文件复制到dir2下了如果dir2目录不存在,则可以直接使用cp -r dir1 dir2即可.如果dir2目录已存在,则需要使用cp -r dir1/. dir2如果这时使用cp -r dir1 dir2,则也会将dir1目录复制到dir2中,明显不符合要求.ps:di

【Linux命令】文件和目录操作命令

本文主要用于常用命令的备忘,具体用法可用man查看,或查询其他资料. cd:改变工作目录 ls:列出目录的内容 mkdir:创建一个目录 cat:连接并显示指定的一个和多个文件的有关信息 cp:将给出的文件或目录复制到另一文件或目录中 mv:为文件或目录改名或将文件由一个目录移入另一个目录中 rm:删除一个目录中的一个或多个文件或目录 chown:修改文件所有者和组别 chgrp:改变文件的组所有权 chmod:改变文件的访问权限 grep:在指定文件中搜索特定的内容,并将含有这些内容的行标准输

03_文件和目录常用命令

01. 查看目录内容 1.1 终端实用技巧 1> 自动补全 在敲出 文件/目录/命令 的前几个字母之后,按下 tab 键 如果输入的没有歧义,系统会自动补全 如果还存在其他 文件/目录/命令,再按一下 tab 键,系统会提示可能存在的命令 2> 曾经使用过的命令 按 上/下 光标键可以在曾经使用过的命令之间来回切换 如果想要退出选择,并且不想执行当前选中的命令,可以按 ctrl + c 1.2 ls 命令说明 ls 是英文单词 list 的简写,其功能为列出目录的内容,是用户最常用的命令之一,

文件和目录常用命令

目标 查看目录内容 ls 切换目录 cd 创建和删除操作 touch rm mkdir 拷贝和移动文件 cp mv 查看文件内容 cat more grep 其他 echo 重定向 > 和 >> 管道 | 01. 查看目录内容 1.1 终端实用技巧 1> 自动补全 在敲出 文件/目录/命令 的前几个字母之后,按下 tab 键 如果输入的没有歧义,系统会自动补全 如果还存在其他 文件/目录/命令,再按一下 tab 键,系统会提示可能存在的命令 2> 曾经使用过的命令 按 上/下

apue第四章 文件和目录

函数stat,fstat,fstatat, lstat #include <sys/stat.h> int stat(const char *restrict pathname, struct stat *restrict buf); int fstat(int fd, struct stat *buf); int lstat(const char *restrict pathname, struct stat *restrict buf); int lstat(int fd, const c

APUE(4)---文件和目录 (2)

umask函数为进程设置文件模式创建屏蔽字,并返回之前的值,这是少数几个没有出错返回函数中的一个.其中cmask是9个常量(S_IR/W/XUSR.S_IR/W/XGRP.S_IR/W/XOTH)中的若干个按位“或”构成的. #include<sys/stat.h> mode_t umask(mode_t cmask); //返回值:之前的文件模式创建屏蔽字 #include<apue.h> #include<fcntl.h> #define RWRWRW (S_IRU