(一)linux文件扩展名
在linux中,扩展名是用来区分不同的文件。
(二)文件类型
Linux系统把一切都看作文件,Linux有7种文件类型:普通(regular file)文件、目录(directory)文件、符号(Link)链接、字符(character)设备文件、块(block)设备文件、管道(pipe)文件、嵌套字(socket)文件。
其中文件、目录、符号链接会占用磁盘空间来存储,而块设备、字符设备、套接字、管道是伪文件,并不占用磁盘空间。
1.普通文件(regular file)第一个字符为[ - ]
包括:
①纯文本档(ASCII):这是Linux系统中最多的一种文件类型,称为纯文本档。是因为内容为我们人类可以直接读到的数据,例如数字、字母等等。
②二进制文件(binary): 你的Linux中的可执行文件(scripts, 文字型批处理文件不算)就是这种格式的。
③数据格式文件(data):有些程序在运作的过程当中会读取某些特定格式的档案,那些特定格式的档案可以被称为数据文件 (data file)。一般用cat看到的都是乱码。
2.目录(directory): 第一个字符为[ d ]
3.连接文件(link)第一个字符为[ l ]
关于软链接
软链接文件有点类似于Windows的快捷方式。它实际上是特殊文件的一种。在符号连接中,文件实际上是一个文本文件,其中包含的有另一文件的位置信息。
1.产生软链接的语法
# ln -s 源文件或目录 目标文件或目录
2.软链接也叫符号链接,它和硬链接有所不同,软链接文件只是其源文件的一个标记。当我们删除了源文件后,链接文件不能独立存在,虽然仍保留文件名,但我们却不能查看软链接文件的内容了。
值得我们注意的是:当我们修改链接文件的内容时,就意味着我们在修改源文件的内容。当然源文件的属性也会发生改变,链接文件的属性并不会发生变化。当我们把源文件删除后,链接文件只存在一个文件名,因为失去了源文件,所以软链接文件也就不存在了。这一点和硬链接是不同的;
3.示例
touch f1(创建一个f1的文件)
ln f1 f2 创佳一个f2的硬连接
ln -s f1 f3 创建一个f3的软连接
此时如果删除f3,对f1,f2无影响;如果删除f2,对f1,f3也无影响,如果删除f1,那么因为f2也应用f1,所以并不影响f2节点的,touch 创建的文件仍然存在;但是此时f3因为是软连接,导致f3失效。如果删除f1,f2 ,那么touch 创建的文件会被删除
4.设备和设备文件
快设备文件,即一些存储文件,如硬盘、软盘等,第一个字符为[ b ]
(注意:设备文件最好不要随便修改,链接文件说白了就是win下的快捷方式。)
字符设备文件,即一些串行端口的接口文件,如键盘、鼠标等,第一个字符为[ c ]
5.套接字(sockets)第一个字符为[ s ]
还被称为数据接口文件,这种类型的文件通常被用在网络上的数据连接。我们可以启动一个程序来监听客户端的请求,而客户端就可以通过数据接口文件来进行数据通信。
6.管道(FIFO,pipe)第一个字符为[ p ]
FIFO也是一种特殊的文件类型,他主要的目的解决多个程序同时访问一个文件所造成的错误问题,first-in-first-out。
(三)文件描述符
文件描述符(file descriptor,fd)是Linux内核为了高效管理已被打开的文件所创建的索引,其是一个非负整数(通常是小整数),用于指代被打开的文件,所执行I/O操作的系统调用都通过文件描述符。
程序在开始运行时,系统会自动打开三个文件描述符,0是标准输入,1是标准输出,2是标准出错。
POSIX标准要求每次打开文件时(含socket)必须使用当前进程中最小可用的文件描述符号码,因此第一次打开的文件描述符一定是3。
open()系统调用
int open(const char *path,int oflag,.../*mode_t mode*/);
open()系统调用用来打开一个文件,并返回一个文件描述符(file description),并且该文件描述符是当前进程最小、未使用的文件描述符数值。
1. 参数
2.设置非租塞模式方式
int fd;
fd = open(“text.txt”, O_RDWR|O_CREAT|O_TRUNC, 0666);
fd = open(“text.txt”, O_WRONLY|O_APPEND);
create()系统调用
int creat(const char *path, mode_t mode);
此函数用来创建一个新文件并返回其fd。它等价于open(path,O_WRONLY|O_CREAT|O_TRUNC, mode);
int fd;
fd=creat(“text.txt”, 0644);
close()系统调用
int close(int fd);
该函数用来关闭一个打开的文件描述符,关闭一个文件时还会释放该进程加在该文件上的所有记录锁。当一个进程终止时,内核将会自动关闭它所有打开的文件。
write()系统调用
ssize_t write(int fd, const void *buf,size_t nbytes);
write()函数用来往打开的文件描述符fd指向的文件中写入buf指向的数据,其中nbytes指定要写入的数据大小。如果返回值<0则说明写入出错,譬如尝试往一个只读的文件中写入则会抛错,错误的原因系统会保存到errno变量中去。如果>0则为实际写入的数据大小。
lseek()系统调用
off_t lseek(int fd, off_t offset, int whence);
我们在从文件里读出内容,或往文件写如内容的时候都有一个起始地址,这个起始地址就是当前文件偏移量,当我们对文件进行读写的时候都会使文件偏移量往后偏移。这点就类似于我们打开记事本开始编辑文本时的光标,我们读或写入时从光标所在位置开始读写,每读写一个字节都会使光标往后偏移。
通过lseek()这个函数我们可以调整文件偏移量的地址。
whence可以是一下三个值:
而offset就是相对于whence 的偏移量,譬如:
lseek(fd, 0, SEEK_SET); 将文件偏移量设置到了文件开始的第一个字节上;
lseek(fd, 0, SEEK_END); 将文件偏移量设置到文件最后一个字节上;
lseek(fd, -1, SEEK_END); 将文件偏移量设置到文件最后的倒数第一个字节上;
read()系统调用
ssize_t read(int fd, void *buf, size_t nbytes);
read()函数用来从打开的文件描述符对应的文件中读取数据放到buf指向的内存空间中去,最多不要超过nbytes个字节,这里的nbytes一般是buf剩余的空间大小。如read成功,则返回实际读到的字节数(由nbytes或读到文件尾决定,其中EOF宏用来判断是否到了文件尾),如果返回值小于0则表示出错,如尝试读一个没有权限读的文件时就会抛错。
dup()和dup2()系统调用
int dup(int fd);
int dup2(int fd, int fd2);
这两个函数都可以用来复制一个新的文件描述符来指向fd对应的文件。这两个系统调用经常用在标准输入、标准输出、标准出错重定向。
dup()返回的新文件描述符一定是当前可用文件描述符中的最小数值;
dup2可以用fd2参数来指定新的文件描述符。如果fd2已经打开,则先关闭。如fd等于fd2, 则dup2返回fd2, 而不关闭它。
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char *argv)
{
int fd = -1;
fd = open("std.txt", O_RDWR|O_CREAT|O_TRUNC, 0666);
if(fd < 0)
{
printf("Open file failure: %s\n", strerror(errno));
return ;
}
dup2(fd, STDIN_FILENO); //标准输入重定向到 std.txt 文件中去
dup2(fd, STDOUT_FILENO); //标准输出重定向到 std.txt 文件中去
dup2(fd, STDERR_FILENO); //标准出错重定向到 std.txt 文件中去
printf("fd=%d\n", fd);
close(fd);
}
#include
#include
#include
#include
#include
#include
#define BUFSIZE 1024
#define MEG_STR "hello world\n"
int main(int argc,char **argv)
{
int fd = -1;
int rv = -1;
char buf[BUFSIZE];
fd=open("/home/wyz/work/test.txt",O_RDWR|O_CREAT|O_TRUNC,0666);
if(fd < 0)
{
printf("open/create file test.txt failure");
perror("message");
return 0;
}
printf("open file returned file Description [%d]\n",fd);
if( (rv=write(fd,MEG_STR,strlen(MEG_STR))) < 0 )
{
printf("write %d bytes into file faliure: %s\n",rv,strerror(errno));
goto cleanup;
}
memset(buf,0,sizeof(buf));
lseek(fd,0,SEEK_SET);
if( (rv=read(fd,buf,sizeof(buf))) < 0)
{
printf("read data from file failure: %s\n",strerror(errno));
goto cleanup;
}
printf("read %d bytes data from file:\n%s\n",rv,buf);
cleanup:
close(fd);
return 0;
}