一.linux下包含的文件类型 1.普通文件 2.目录文件 3.字符特殊文件 4.块特殊文件 5.FIFO 6.套接字 7.符号连接
二.linux的访问文件控制
chmod使用语法
$ chmod [options] mode[,mode] file1 [file2 ...]
使用ls命令的查看文件或目录的属性
$ ls -l file
chmod命令可以使用八进制数来指定权限。文件或目录的权限位是由9个权限位来控制,每三位为一组,它们分别是文件所有者(user)的读、写、执行,用户(group)的读、写、执行以及(other)其它用户的读、写、执行。历史上,文件权限被放在一个比特掩码中,掩码中指定的比特位设为1,用来说明一个类具有相应的优先级。
chmod的八进制语法的数字说明;
r 4 w 2 x 1 - 0
所有者的权限用数字表达:属主的那三个权限位的数字加起来的总和。如rwx ,也就是4+2+1 ,应该是7。
用户组的权限用数字表达:属组的那个权限位数字的相加的总和。如rw- ,也就是4+2+0 ,应该是6。
其它用户的权限数字表达:其它用户权限位的数字相加的总和。如r-x ,也就是4+0+1 ,应该是5。
my_chomd.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc,char **argv)
{
int mode; //权限
int mode_u; //所有者权限
int mode_g; //所属者权限
int mode_o; //其他用户权限
char *path;
if(argc < 3){
printf("%s <mode num> <target file \n>",argv[0]);
exit(0);
}
mode = atoi(argv[1]);
if(mode > 777 || mode < 0){
printf("mode num error!\n");
exit(0);
}
mode_u = mode / 100;
mode_g = (mode % 100) / 10;
mode_o = mode % 10; // 或者mode_o= mode - (mode_u * 100) - (mode_g * 10);
mode = (mode_u * 8 * 8) + (mode_g * 8)+ mode_o; // 八进制转化
path = argv[2];
if(chmod(path,mode) == -1){
perror("chmod error");
exit(1);
}
return 0;
}
在程序中,权限更改成功返回0,失败返回-1,错误代码存于系统预定义变量errno中。
上面的程序中,atoi这个函数调用是将字符串转换成整型,例如:atoi("777")的返回值为整型的777.对于chmod函数,第二个参数一般用上面列出来的宏之间取或运算。
三.文件的创建打开和关闭
1.open函数
调用o p e n函数/以打开或创建一个文件。
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open (const char * pathname ,int oflag , .../* ,mode_t mode */)
返回:若成功为文件描述符,若出错为- 1
我们将第三个参数写为 . . .,这是ANSI C说明余下参数的数目和类型可以变化的方法。对于o p e n函数而言,仅当创建新文件时才使用第三个参数。在此函数原型中此参数放置在注释中。
pathname 是要打开或创建的文件的名字。 oflag参数可用来说明此函数的多个选择项。用下列一个或多个常数进行或运算构成 oflag 参数 (这些常数定义在< fcntl .h >头文件中):
• O_RDONLY 只读打开。
• O_WRONLY 只写打开。
• O_RDWR 读、写打开。
在这三个常数中应当只指定一个。下列常数则是可选择的:
• O_APPEND 每次写时都加到文件的尾端。
• O_CREAT 若此文件不存在则创建它。使用此选择项时,需同时说明第三个参数 mode,用其说明该新文件的存取许可权位。
• O_EXCL 如果同时指定了O _ C R E AT,而文件已经存在,则出错。这可测试一个文件是否存在,如果不存在则创建此文件成为一个原子操作。
• O_TRUNC 如果此文件存在,而且为只读或只写成功打开,则将其长度截短为 0。
• O_NOCTTY 如果 pathname 指的是终端设备,则不将此设备分配作为此进程的控制终端。
• O_NONBLOCK 如果 pathname 指的是一个F I F O、一个块特殊文件或一个字符特殊文件,则此选择项为此文件的本次打开操作和后续的 I / O操作设置非阻塞方式。
2.creat 函数
也可用 creat 函数创建一个新文件。
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int creat ( const char * pathname ,mode_t mode)
返回:若成功为只写打开的文件描述符,若出错为- 1
注意,此函数等效于:
open (pathname ,O_WRONL |O_CREAT | O_TRUNC , mode );
creat 的一个不足之处是它以只写方式打开所创建的文件。在提供open 的新版本之前,如果要创建一个临时文件,并要先写该文件,然后又读该文件,则必须先调用creat ,close,然后再调用open 。现在则可用下列方式调用 open :
open ( pathname , O _ R D W R| O _ C R E A T|O_TRUNC, mode ) ;
3.close函数
可用 close 函数关闭一个打开文件:
#include <unistd.h>
int close (int filedes );
返回:若成功为 0,若出错为- 1
关闭一个文件时也释放该进程加在该文件上的所有记录锁。
当一个进程终止时,它所有的打开文件都由内核自动关闭。很多程序都使用这一功能而不显式地用close关闭打开的文件
四.文件的读写
1.read函数
用read函数从打开文件中读数据。
#include <unistd.h>
ssize_t read (int fd ,void *buf ,size_count );
返回:读到的字节数,若已到文件尾为 0,若出错为- 1
如 read 成功,则返回读到的字节数。如已到达文件的尾端,则返回 0。
有多种情况可使实际读到的字节数少于要求读字节数:
• 读普通文件时,在读到要求字节数之前已到达了文件尾端。例如,若在到达文件尾端之前还有3 0个字节,而要求读 1 0 0个字节,则 read 返回3 0,下一次再调用 read 时,它将返回 0 (文件尾端)。
• 当从终端设备读时,通常一次最多读一行
• 当从网络读时,网络中的缓冲机构可能造成返回值小于所要求读的字节数。
• 某些面向记录的设备,例如磁带,一次最多返回一个记录。读操作从文件的当前位移量处开始,在成功返回之前,该位移量增加实际读得的字节数。
其返回值必须是一个带符号整数( ssize_t ),以返回正字节数、 0(表示文件尾端)或- 1(出错)。最后,第三个参数在历史上是一个不带符号整数,以允许一个 1 6位的实现可以一次读或写至 6 5 5 3 4个字节。
2.write函数
用 write 函数向打开文件写数据。
#include <unistd.h>
ssize_t write (int fd ,const void *buf ,size_t count )
返回:若成功为已写的字节数,若出错为- 1
其返回值通常与参数 n b y t e s的值不同,否则表示出错。 w r i t e出错的一个常见原因是:磁盘已写满,或者超过了对一个给定进程的文件长度限制
对于普通文件,写操作从文件的当前位移量处开始。如果在打开该文件时,指定了O _ A P P E N D选择项,则在每次写操作之前,将文件位移量设置在文件的当前结尾处。在一次成功写之后,该文件位移量增加实际写的字节数。
五.文件的读写指针的移动
lseek函数
每个打开文件都有一个与其相关联的“当前文件位移量”。它是一个非负整数,用以度量从文件开始处计算的字节数。
通常读、写操作都从当前文件位移量处开始,并使位移量增加所读或写的字节数。按系统默认,当打开一个文件时,除非指定 O _ A P P E N D选择项,否则该位移量被设置为 0。
可以调用lseek 显式地定位一个打开文件。
#include <sys/types.h>
#include <unistd.h>
off_t lseek (int fildes ,off_t offset ,int whence ) ;
返回:若成功为新的文件位移,若出错为- 1
对参数offset 的解释与参数w h e n c e的值有关。
• 若 whence 是 SEEK_SET ,则将该文件的位移量设置为距文件开始处 offset 个字节。
• 若 whence 是 SEEK_CUR,则将该文件的位移量设置为其当前值加offset, offset可为正或负。
• 若 whence 是 SEEK_END ,则将该文件的位移量设置为文件长度加offset, offset可为正或负。
若 lseek 成功执行,则返回新的文件位移量,为此可以用下列方式确定一个打开文件的当前
位移量:
off_t
currpos;
currpos = lseek(fd, 0, SEEK_CUR);
这种方法也可用来确定所涉及的文件是否可以设置位移量。如果文件描述符引用的是一个管道或F I F O,则 lseek 返回-1,并将 errno 设置为 EPIPE 。