unix环境高级编程笔记(5)—— 文件和目录(2)

1 文件截短

有时我们需要把文件尾端处截去一些数据以缩短文件,将一个文件清0是一个特例。在打开文件时使用O_TRUNC标志可以做到这一点。

#include <unistd.h>
int truncate(const char *pathname,off_t length);
int ftruncate(int filedes,off_t length);
                                        成功返回0,出错返回-1.

如果length 小于文件长度,则使文件长度截断至length,剩下的不可访问。如果length大于文件长度,则与系统的实现有关,可能把原文件尾到现在文件尾的数据读作0(形成空洞)。

2 link、unlink、remove和rename函数

2.1 link、unlink函数

#include <unistd.h>
int link(const char *existingpath,const char *newpath);
int unlink(const char *pathname);
                                            成功返回0、出错返回-1.

link创建一个新目录项newpath,它引用现有的文件existingpath,如果newpath已经存在则出错。

unlink 使文件pathname所引用文件的链接计数减1.如果到0则删除该文件。但是,只要有进程打开了该文件,其内容也不会被删除。关闭一个文件时,内核先检查打开文件的进程数,如果达到0,再检查其链接数,如果也为0就删除该文件。

unlink的这种性质经常被用来确保程序崩溃时,它所创建的临时文件也不会留下来,先用open打开临时文件,然会对它unlink。等进程结束或者崩溃时,文件自动被删除。

如果pathname是符号链接,unlink删除该符号链接而不会删除该符号链接所指向的文件。

2.2 remove函数

我们也可以用remove解除对一个文件或目录的链接。

#include <stdio.h>
int remove(const char *pathname);
                                成功返回0、出错返回-1.

对于文件,remove和unlink相同。对于目录,remove的功能与rmdir相同,用于删除一个空目录。不能删除非空目录!

2.3 rename函数

文件或目录用rename更名

#include <stdio.h>
int rename(const char *oldname,const char *newname);
                                                    成功返回0,失败返回-1.

当oldname是文件时:则为此文件或符号链接更名,如果newname已存在且不是引用一个目录,则删除该项,使oldname更名为newname。

当oldname是目录时:则为此目录更名,如果newname已经存在,且是一个空目录,则先将其删除,然后将oldname更名为newname。特别的,newname中不能使用oldname做为其前缀。

3 文件时间

对于每个文件,有三个与之相关的时间。存在与stat结构中。

          st_atime        文件数据的最后访问时间

          st_mtime          文件数据的最后修改时间

          st_ctime         i节点状态的最后更改时间

有许多操作更改文件的i节点状态:更改文件的访问权限、用户ID、链接数等。但并没有修改文件的实际内容。

系统不保存对i节点的最后访问时间,所以access和stat函数并不修改任何时间。

3.1 utime函数

一个文件的访问时间和修改时间可以用utime更改。

#include <utime.h>
int utime(const char *pathname,struct utimbuf *times);
                                                    成功返回0,出错返回-1.  

struct utimbuf{

  time_t  actime;    /* access time */

  time_t  modtime;   /* modification time */

};

此结构的时间是日历时间,即自1970以来的秒数。

如果times为NULL。则使用当前时间设置文件的对应时间,进程必须有相应的权限。

如果times不为空。则设置为相应的值。

特别得,我们不能更改st_ctime的值,调用utime时自动更新。

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <utime.h>
int main(int argc,char *argv[])
{
    int i,fd;
    struct stat statbuf;
    struct utimbuf timebuf;
    for(i = 1;i < argc;i++)
    {
        if(stat(argv[i],&statbuf) < 0 )
            {
                printf("stat error !\n");
                continue;
            }
        if(open(argv[i],O_RDWR | O_TRUNC) < 0)
        {
            printf("open error!\n");
            continue;
        }
        timebuf.actime = statbuf.st_atime;
        timebuf.modtime = statbuf.st_mtime;
        if(utime(argv[i],&timebuf) < 0)
        {
            printf("utime error!\n");
            continue;
        }
    }
    return 0;
}

编译运行:

[email protected]:/program# ls -l test.c
-rw-r--r-- 1 debian debian 63 Nov  9 21:21 test.c
[email protected]:/program# ls -lu test.c
-rw-r--r-- 1 debian debian 63 Nov 19 11:02 test.c
[email protected]:/program# ls -lc test.c
-rw-r--r-- 1 debian debian 63 Nov  9 21:21 test.c
[email protected]:/program# date
Wed Nov 19 20:12:42 CST 2014
[email protected]:/program# ./4-6 test.c
[email protected]:/program# ls -l test.c
-rw-r--r-- 1 debian debian 0 Nov  9 21:21 test.c
[email protected]:/program# ls -lu test.c
-rw-r--r-- 1 debian debian 0 Nov 19 11:02 test.c
[email protected]:/program# ls -lc test.c
-rw-r--r-- 1 debian debian 0 Nov 19 20:12 test.c
[email protected]:/program# ^C
[email protected]:/program#

从上面的结构可以看到,当调用stat函数时,最后修改时间和最后访问时间都没有变。但是,更改状态时间为程序运行的时间。

时间: 2024-12-15 05:54:03

unix环境高级编程笔记(5)—— 文件和目录(2)的相关文章

UNIX环境高级编程笔记之文件I/O

一.看图说话 一图胜过千言,看图! 二.唠一唠 在写之前,先唠几句,<UNIX环境高级编程>,简称APUE,这本书简直是本神书,像我这种小白,基本上每看完一章都是“哇”这种很吃惊的表情.其实大概三年前,那会大三,我就买了这本书,也看过一些,但好像没有留下什么印象,今天再看,依然觉得像新的一样.很大的原因我想是一直以来都在用windows(用windows做开发为什么学不到真正的技术,我想大家都懂的),当然知识结构不完整,学习能力这些就不说了.所以,对于那些致力于想在Linux下做开发的人来说,

《UNIX环境高级编程》---4文件和目录

文件和目录 一. stat 结构和权限相关 四个stat函数:返回文件或者目录的信息结构: #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 fstat

4.28 UNIX环境高级编程 笔记

int dup(int filedes); int dup2(int filedes,int filedes2); 这两个函数都可以实现复制一个现存的文件描述符,但是dup一定返回当前可用最小文件描述符,dup2可以用filedes2参数指定新描述符数值.如果filedes2已经打开,则先将其关闭.如果filedes等于filedes2,则返回filedes2而不关闭. 这些函数返回的新文件描述符与参数参数filesdes共享同一个文件表项. 图3 执行dup之后的内核数据结构 dup2是原子操

unix环境高级编程笔记(4)—— 文件和目录(1)

1 引言 本文将描述文件系统的一些特征和文件的性质,从stat函数开始,逐个讲解stat结构的成员以了解文件的属性. 2 stat,fstat 和 lstat函数 #include <sys/stat.h> int stat(const char *restrict pathname,struct stat *restrict buf); int fstat(int filedes,struct stat *restrict buf); int lstat(const char *restri

unix环境高级编程笔记(2)-- 文件I/O之不带缓冲的I/O

1 引言 不带缓冲区的I/O(unbuffered I/o)是指每个read 和 write 都调用内核中的一个系统调用,这些不带缓冲区的I/O 不是ISO C 的组成部分. 2 文件描述符 每个打开的文件都通过文件描述符引用,文件描述符是一个非负整数.open 和 create 函数返回的文件描述符供 read write 和 close 使用. unix中文件描述符0与标准输入相关联,文件描述符1与标准输出相关联,文件描述符2与标准出错输出相关联. 3 不带缓冲区的I/O函数 下面介绍6个常

unix环境高级编程笔记(3)-- 文件I/O(2)

本文讨论如何在多个进程间共享文件,以及所涉及的内核数据结构.然后会介绍dup,dup2,fcntl等函数的使用. 1 数据结构 内核使用三种数据结构表示打开的文件: (1)每个进程在进程表中都有一个记录项,记录项中有一张打开文件文件描述符表,每项包括: a )文件描述符标志(close_on_exec) b)指向一个文件表的指针 (2)内核为所有打开的文件维护一张文件表,每个文件表项包括: a)文件状态标志(读 写  添加  同步和非阻塞) b)  当前文件偏移量 c)  指向v节点的指针 (3

unix环境高级编程笔记(6)—— 文件和目录(3)

这一节主要是讲目录的操作,涉及创建目录.删除目录.读取目录等 1 mkdir 和 rmdir 用mkdir创建目录,用rmdir删除目录. #include <sys/stat.h> int mkdir(const char *pathname,mode_t mode); 成功返回0,出错返回-1. 此函数创建一个新的空目录,. 和.. 自动创建,文件访问权限mode由进程的文件模式创建屏蔽字进行修改.(必须指定一个执行权限位) #include <unistd.h> int rm

《UNIX环境高级编程》---3.文件I/O

一.打开.创建文件.关闭文件 文件描述符:一个非负整数,范围是0~OPEN_MAX-1.内核用它来标识进程正在访问的文件.当进程创建时,默认为它打开了3个文件描述符,它们都链接向终端: 0: 标准输入 1: 标准输出 2: 标准错误输出 通常我们应该使用STDIN_FILENO,STDOUT_FILENO和 STDERR_FILENO来替代这三个幻数,从而提高可读性.这三个常量位于<unistd.h>中. 2. open和openat函数:打开文件 ``` #include<fcntl.

UNIX环境高级编程笔记之高级I/O

本章说明了很多高级I/O功能: 非阻塞I/O——发一个I/O操作,不使其阻塞,记录锁,STREAMS机制 I/O多路转接——select和poll函数 readv和writev函数,以及存储映射I/O(mmap函数)