软连接与硬连接 软连接 ln -s file file.s #ln [选项]... [-T] 目标 链接名
类似于windows的快捷方式,file.s中存储的是访问路径,但是是相对的,如果将file.s的位置移动后,无法使用,如果想要使用绝对路径,则使用绝对路径创建
ln -s /home/kozakemi/test/linux_shell/file file.soft
这样操作后任意位置均可访问,因此,为了创建软连接是,尽量使用绝对路径创建软连接
实际上其原理为软连接文件存储的是路径
创建的软连接,文件名与日期均不同
文件类型为l
硬连接 创建的软连接权限为全开放,但是文件是否可被操作,是由源文件决定
这两个文件任意修改一个,均会更改源文件,文件名不同,而日期一致
原理是两个文件为Inode一致,因此修改一个文件时,会同时修改是有的Inode一致的文件,及硬连接的文件,linux为每个文件赋予唯一的Inode
当删除时就不是这个问题,做法是将硬连接计数减1
文件类型由源文件决定
系统调用 系统调用函数属于操作系统的一部分,是为了提供给用户进行操作的接口(API函数),使得用户态运行的进程与硬件设备(如CPU、磁盘、打印机、显示器)等进行交互。
man 太男人了
这是一个非常好用的工具,在linux查询c库与系统调用十分便捷
1 可执行程序或 shell 命令 2 系统调用(内核提供的函数) 3 库调用(程序库中的函数) 4 特殊文件(通常位于 /dev) 5 文件格式和规范,如 /etc/passwd 6 游戏 7 杂项(包括宏包和规范), 如 man(7),groff(7), man-pages(7) 8 系统管理命令(通常只针对 root 用户) 9 内核例程 [非标准
文件IO open() 概述 open, creat - 打开和/或创建一个文件
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open (const char *pathname, int flags) ;int open (const char *pathname, int flags, mode_t mode) int creat (const char *pathname, mode_t mode) ;
参数 参数 pathname
为文件路径
flages
是通过 O_RDONLY
, O_WRONLY
或 O_RDWR
(指明 文件 是以 只读 , 只写 或 读写 方式 打开的)与下面的 零个 或 多个 可选模式 按位 -or 操作 得到的
O_CREAT 若文件 不存在 将 创建 一个 新 文件. 新 文件 的 属主 (用户ID) 被 设置 为 此 程序 的 有效 用户 的 ID. 同样 文件 所属 分组 也 被 设置 为 此 程序 的 有效 分组 的 ID 或者 上层 目录 的 分组 ID (这 依赖 文件系统 类型 ,装载选项 和 上层目录 的 模式, 参考,在 mount(8) 中 描述 的 ext2 文 件系统 的 装载选项 bsdgroups 和 sysvgroups ) O_APPEND 文件 以 追加 模式 打开 . 在 写 以前 , 文件 读写 指针 被 置 在 文件 的 末尾 . as if with lseek. O_APPEND may lead to corrupted files on NFS file systems if more than one process appends data to a file at once. This is because NFS does not support appending to a file, so the client kernel has to simulate it, which can't be done without a race condition. # 其余详见`man 2 open`
mode
创建文件时指定权限
S_IRWXU 00700 允许 文件 的 属主 读 , 写 和 执行 文件 S_IRUSR (S_IREAD) 00400 允许 文件 的 属主 读 文件 S_IWUSR (S_IWRITE) 00200 允许 文件 的 属主 写 文件 # 其余详见`man 2 open`
返回值 返回值为int类型,一般从3开始递增,
文件描述符 0:标准输入(stdin) 文件描述符 1:标准输出(stdout) 文件描述符 2:标准错误输出(stderr) 以上三个描述符被系统占用,因此一般从3开始,例如下面的示例代码
示例代码 #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <errno.h> #include <string.h> int main () { int fd; fd = open("tmp.txt" , O_WRONLY); if (fd == -1 ) { perror("Error opening tmp.txt" ); printf ("Error opening tmp.txt: %s\n" ,strerror(errno)); } printf ("%d\n" , fd); fd = open("tmp.txt" , O_WRONLY | O_APPEND); if (fd == -1 ) { perror("Error opening tmp.txt" ); printf ("Error opening tmp.txt: %s\n" ,strerror(errno)); } printf ("%d\n" , fd); fd = open("Fol.txt" , O_RDONLY | O_CREAT, 0777 ); if (fd == -1 ) { perror("Error opening Fol.txt" ); printf ("Error opening Fol.txt: %s\n" ,strerror(errno)); } printf ("%d\n" , fd); return 0 ; }
目录文件结构
[kozakemi@kozakemi-arch linux_ccode]$ ls -l 总计 8 -rw-r--r-- 1 kozakemi kozakemi 6 10月16日 23:29 1.txt -rw-r--r-- 1 kozakemi kozakemi 563 10月16日 23:50 file_w.c -rwxr-xr-x 1 kozakemi kozakemi 0 10月16日 23:46 Fol.txt -rw-r--r-- 1 kozakemi kozakemi 0 10月16日 23:47 tmp.txt
执行结果
[kozakemi@kozakemi-arch linux_ccode]$ gcc '/home/kozakemi/test/linux_ccode/file_w.c' && ./a.out 3 4 5
write() 概述 在一个文件描述符上执行写操作
#include <unistd.h> ssize_t write (int fd, const void *buf, size_t count) ;
参数 fd
文件描述符,open的返回值
buf
写入的字符串
count
写入的大小
返回值 ssize_t
为写入的字节数
示例代码 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <unistd.h> #include <errno.h> #include <string.h> int main () { int fd; ssize_t strno; fd=open("Fol.txt" ,O_WRONLY|O_APPEND); char infile_str[]="asdasdasd\n" ; if (-1 ==fd) { printf ("error Fol.txt: %s" ,strerror(errno)); perror("Fol.txt" ); }else { strno=write(fd, infile_str, strlen (infile_str)); printf ("%d=%d=%d-1" ,strno,strlen (infile_str),sizeof (infile_str)); } return 0 ; }
read() 概述 在文件描述符上执行读操作
#include <unistd.h> ssize_t read (int fd, void *buf, size_t count) ;
参数 fd
文件描述符,open的返回值
buf
读出的字符串
count
读出的大小
需要注意的是count
不要大于buf
值(必定报错[1] 17806 IOT instruction (core dumped)
),更不要大于文件中内容的大小否则会出现不可预料的错误(虽然我测试时未遇到) 返回值 ssize_t
为读出的字节数
示例代码 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <unistd.h> #include <errno.h> #include <string.h> int main () { int fd; ssize_t strno; int readsize=10 ; fd=open("Fol.txt" ,O_RDONLY); char file_oustr[20 ]="" ; if (-1 ==fd) { printf ("error Fol.txt: %s" ,strerror(errno)); perror("Fol.txt" ); }else { strno=read(fd, file_oustr, readsize); printf ("%d,%s" ,strno,file_oustr); } return 0 ; }
close() 概述 关闭一个文件描述符
#include <unistd.h> int close (int fd) ;
参数 fd
文件描述符
返回值 -1
为关闭失败,0
为关闭成功
示例代码 #include <unistd.h> 。。。 fd=open("Fol.txt" ,O_RDONLY); 。。。 if (-1 ==close(fd)){ printf ("error close file: %s" ,strerror(errno)); return -1 ; }
lseek() 这是一个系统调用
概述 修改文件的描述符,偏移位置
#include <unistd.h> off_t lseek (int fd, off_t offset, int whence) ;
参数 fd
文件描述符
offset
偏移量
whence
偏移方式
SEEK_SET
:偏移到文件头+ 设置的偏移量SEEK_CUR
:偏移到当前位置+设置的偏移量SEEK_END
:偏移到文件尾置+设置的偏移量返回值 off_t
设置之后的文件偏移量,操作失败时返回-1
,成功后返回偏移量
示例程序 查看当前的位置
#include <fcntl.h> #include <stdio.h> #include <unistd.h> #include <errno.h> int main () { int fd,ret; fd=open("Fol.txt" ,O_RDWR); ret=lseek(fd,0 ,SEEK_CUR); printf ("%d\n" ,ret); perror("lseek" ); return 0 ; }
查看文件大小
#include <fcntl.h> #include <stdio.h> #include <unistd.h> #include <errno.h> int main () { int fd,ret; fd=open("Fol.txt" ,O_RDWR); ret=lseek(fd,0 ,SEEK_END); printf ("%d\n" ,ret); perror("lseek" ); return 0 ; }
将字符串插入到指定的位置后
#include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <string.h> int main () { int fd,ret; char a[]="JMU WELCOME" ; fd=open("hello1.txt" ,O_RDWR|O_CREAT,0777 ); ret=lseek(fd,1000 ,SEEK_END); write(fd,a,strlen (a)); printf ("%d\n" ,ret); return 0 ; }