unix下的文件和目录详解以及操作方法
前言:unix下一切东西都是文件,一共有7种不同的文件,前一篇博客已经讲解的很清楚了,不懂的可以看看这里。当然,博主知道有些朋友比忙,没时间看,那我就简单点讲讲这7种文件都有哪些吧。
文件类型包括在stat结构的st_mode成员中,下面是这7种文件类型的判断方法: |
当然这些文件都是有访问权限的,很巧这些权限也是在一个叫struct stat这个结构体中
结构体struct stat中的成员st_mode值包含了对文件的访问权限位,任何类型的文件都有访问权限(access permission)。每个文件有9个访问权限,可以它们分为3类,u表示用户(所有者)、g表示组、o表示其他 st_mode屏蔽 含义 S_IRGRP 组读 S_IROTH 其他读 |
那么问题来了既然有权限,我们怎么知道这些权限呢?当然这不是难事,一个access函数就可以解决问题了
函数描述:按实际用户ID和实际组ID进行访问权限测试 |
这是access函数的具体用法的代码(argv[1]必须是一个已经存在的文件):
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h> int main(int argc,char **argv)
{
if(argc != )
{
printf("argc must equal to two!\n");
exit();
} if(access(argv[],F_OK)) //判断文件是否存在
{
printf("%s not existence!\n",argv[]);
exit();
} if(access(argv[],R_OK)) //判断文件是否可读
{
printf("%s not read permission\n",argv[]);
}
else
{
printf("%s have read permission\n",argv[]);
} if(access(argv[],W_OK)) //判断文件是否可写
{
printf("%s not write permission\n",argv[]);
} else
{
printf("%s have write permission\n",argv[]);
}
if(access(argv[],X_OK)) //判断文件是否可执行
{
printf("%s not execute permission\n",argv[]);
}
else
{
printf("%s have execute permission\n",argv[]);
} return ;
}
在ubuntu下运行:
当然了既然有权限,那么我们在创建文件的时候文件权限也是可以自己控制的,umask函数用上场了
函数描述:为进程设置文件模式创建屏蔽字,并返回之前的值 S_IRGRP 组读 S_IROTH 其他读 |
代码的具体用法如下:
#include <sys/stat.h>
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdlib.h> #define RRR (S_IRUSR|S_IRGRP|S_IROTH) //设置文件权限为用户读、组读、其他读
int main(int argc,char *argv[])
{
umask(); //不设置文件屏蔽字
creat("text",RRR); //以用户读、组读、其他读的权限创建文件text.txt //这里也可以用open umask(S_IRUSR|S_IRGRP); //创建用户读、组出屏蔽字
creat("text1",RRR); //最后创建出来的文件只有其他读的权限
return ;
}
既然文件可以创建,当然目录也是可以创建的,mkdir函数就是为创建目录而生的:
函数描述:创建一个空目录,.和..自动创建 S_IRWXU 用户(所有者)、读、写和执行 S_IRWXG 组读、写和执行 S_IRWXO 其他读、写和执行 |
创建目录的具体实现:
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h> int main(int argc,char *argv[])
{
if(mkdir("test.txt",S_IWOTH|S_IRUSR|S_IRGRP) == -) /*以其他写、用户读、组读权限创建一个空目录*/
{
perror("mkdir");
exit();
}
return ;
}
umask函数是在创建文时设置权限,那么在文件被创建之后还能修改权限吗?这时候chmod函数就派上用处了
(1)头文件 #include <sys/stat.h> (2)函数原型 int chmod(const char *path, mode_t mode); (3)参数: a、path:文件路径 b、mode:跟上面midir函数中的成员mode一样,其中的宏位或就可以了 |
改变文件权限的例子:
chmod("text",S_IRUSR|S_IRGRP|S_IROTH); //把text文件的权限改为用户读、组读、其他读
既然权限可以改变权限,当然改个名字也是没问题的,用rename函数轻松解决问题:
(1)头文件 #include <stdio.h> (2)函数原型 int rename(const char *old, const char *new); (3)参数: a、old:文件原来的名字 b、new:新的名字 (4)返回值: 成功:0 失败:-1 |
改变文件名字的例子:
rename("text","hhtext"); //将名字为text的文件改为hhtext
其实文件中还有个小操作就是可以在任何位置截断文件中的内容:
truncate("test",3); //将文件test长度截断为3字节
好了讲了那么多关于文件的权限的东西,是时候讲讲怎么打开一个目录和读目录中的的东西了:
读目录中,要经过三步:打开目录、读目录、关闭目录,对应用到的函数分别为opendir、readdir、closedir。 一、打开目录
()头文件
#include <sys/types.h>
#include <dirent.h>
()函数原型
DIR *opendir(const char *name);
()参数
name:目录名
()返回值:
成功:返回一个DIR*型的目录流
失败:NULL 二、读目录
()头文件
#include <dirent.h>
()函数原型
struct dirent *readdir(DIR *dirp);
()参数
a、dirp:调用opendir函数后返回的DIR*类型的目录流
()返回值:
成功:返回一个(struct dirent)型的结构体
下面是struct dirent结构体的具体内容
struct dirent {
ino_t d_ino; 节点号 /*inode number */
off_t d_off; 偏移到下一个方向 /* offset to the next dirent */
unsigned short d_reclen; 记录长度 /* length of this record */
unsigned char d_type; 文件类型,不支持所有文件系统类型/* type of file; not supportedby all file system types */
char d_name[]; 文件名 /* filename */
};
struct dirent中的成员d_type又有以下几种类型:
DT_BLK 块设备 (This is a block device.)
DT_CHR 字符设备(This is a character device.)
DT_DIR 目录( This is a directory.)
DT_FIFO 命名管道或FIFO(This is a named pipe (FIFO).)
DT_LNK 符号连接(This is a symbolic link.)
DT_REG 普通文件(This is a regular file.)
DT_SOCK UNIX域套接字( This is a UNIX domain socket.)
DT_UNKNOWN 未知类型(The file type is unknown.)
读完或者失败都返回NULL 三、关闭目录
()头文件
#include <sys/types.h>
#include <dirent.h>
()函数原型
int closedir(DIR *dirp);
()参数
a、dirp:用opendir函数后返回的DIR*类型的目录流
()返回值:
成功:
失败:- 四、更改当前工作路径
()头文件 #include <unistd.h>
()函数原型 int chdir(const char *path);
()参数:
a、path:需要更改的路径
()返回值
成功:
失败:-
例子:
chdir("/test.txt"); //当前工作目录更改到test.txt中 五、获得当前工作目录完整的绝对路径
()头文件 #include <unistd.h>
()函数原型 char *getcwd(char *buf, size_t size);
()参数:
a、buf:存放绝对路径的缓冲区
b、size: 缓冲区的大小
()返回值:
成功:返回当前工作目录完整的绝对路径
失败:NULL
例子:
char buf[];
bzero(buf,sizeof(buf));
if(getcwd(buf,sizeof(buf)) == NULL)
{
perror("getcwd");
exit();
}
打开一个目录然后读目录中的文件并把文件名打印出来,具体代码如下:
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> void open_file(char *name)
{
DIR * entry; //opendir返回值
struct dirent *ep; //readdir返回值
char path_name[]; if((entry = opendir(name)) == NULL)
{
perror("opendir");
exit();
} while()
{
if((ep = readdir(entry)) == NULL)
{
break;
}
if(ep->d_name[] == '.') //去掉隐藏文件
{
continue;
} sprintf(path_name,"%s/%s",name,ep->d_name); //拼接两个字符
printf("%s\n",path_name); //输出路径 if(ep->d_type & DT_DIR) //目录 也可以用lstat/stat函数
{
open_file(path_name); //递归打开下一目录
} } closedir(entry);
}
int main(int argc,char *argv[])
{
if(argc != )
{
printf("argv[1] have to a directory!\n");
exit();
}
open_file(argv[]);
return ;
}
运行程序的效果图如下:
最后来点小知识:
**每个文件系统所在的设备都有主、次设备号表示 |
具体代码如下:
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h> int main(int argc,char *argv[])
{
int i;
struct stat buf;
for(i=;i<argc;i++)
{
printf("%s:",argv[i]);
if(stat(argv[i],&buf) == -){
perror("stat");
exit();
} printf("dev = %d/%d",major(buf.st_dev),minor(buf.st_dev));
//判断是否是字特殊文件(S_ISCHR)块特殊文件(S_ISCHR)
if(S_ISCHR(buf.st_mode) || S_ISBLK(buf.st_mode)){
printf(" (%s) rdev = %d/%d",
(S_ISCHR(buf.st_mode)) ? "character" : "block",
major(buf.st_rdev),minor(buf.st_rdev));
}
printf("\n");
}
return ;
}
运行结果:
unix下的文件和目录详解以及操作方法的更多相关文章
- 9.proc目录下的文件和目录详解
1./proc目录下的文件和目录详解 /proc:虚拟目录.是内存的映射,内核和进程的虚拟文件系统目录,每个进程会生成1个pid,而每个进程都有1个目录. /proc/Version:内核版本 /pr ...
- 8.var目录下的文件和目录详解
1./var目录下的文件和目录详解. /var (该目录存放的是不断扩充且经常修改的目录,包括各种日志文件或者pid文件,存放linux的启动日志和正在运行的程序目录(变化的目录:一般是日志文件,ca ...
- 6.etc目录下重要文件和目录详解
1./etc/下的重要的配置文件 /etc(二进制软件包的 yum /rpm 安装的软件和所有系统管理所需要的配置文件和子目录.还有安装的服务的启动命令也放置在此处) /etc/sysconfig/n ...
- Linux:root下的文件-anaconda-ks.cfg详解
anaconda-ks.cfg详解 系统安装的时候生成的一个文件,通过这个文件可以修改成自动安装的脚本,用于自动安装同样配置的系统. 自动生成的启动文件anaconda# Kickstart file ...
- Go语言的GOPATH与工作目录详解
这篇文章主要介绍了Go语言的GOPATH与工作目录详解,本文详细讲解了GOPATH设置.应用目录结构.编译应用等内容,需要的朋友可以参考下 GOPATH设置 go 命令依赖一个重要的环境变量:$GOP ...
- Linux /dev目录详解和Linux系统各个目录的作用
Linux /dev目录详解(转http://blog.csdn.net/maopig/article/details/7195048) 在linux下,/dev目录是很重要的,各种设备都在下面.下面 ...
- Linux /proc目录详解
Linux系统上的/proc目录是一种文件系统,即proc文件系统.与其它常见的文件系统不同的是,/proc是一种伪文件系统(也即虚拟文件系统),存储的是当前内核运行状态的一系列特殊文件,用户可以通过 ...
- 反射实现Model修改前后的内容对比 【API调用】腾讯云短信 Windows操作系统下Redis服务安装图文详解 Redis入门学习
反射实现Model修改前后的内容对比 在开发过程中,我们会遇到这样一个问题,编辑了一个对象之后,我们想要把这个对象修改了哪些内容保存下来,以便将来查看和追责. 首先我们要创建一个User类 1 p ...
- libCURL开源库在VS2010环境下编译安装,配置详解
libCURL开源库在VS2010环境下编译安装,配置详解 转自:http://my.oschina.net/u/1420791/blog/198247 http://blog.csdn.net/su ...
随机推荐
- [技术]浅谈OI中矩阵快速幂的用法
前言 矩阵是高等代数学中的常见工具,也常见于统计分析等应用数学学科中,矩阵的运算是数值分析领域的重要问题. 基本介绍 (该部分为入门向,非入门选手可以跳过) 由 m行n列元素排列成的矩形阵列.矩阵里的 ...
- python--代码统计(进阶版)
在上一篇的随笔中发表了代码统计小程序,但是发表后,我发现,以前写的代码怎么办 写了那么多,怎么就从0开始了呢,,,,我还是个孩子啊,不能这么残忍 于是,代码统计进阶版:统计当前目录下所有指定文件类型的 ...
- NYOJ--42--dfs--一笔画问题
/* Name: NYOJ--42--一笔画问题 Author: shen_渊 Date: 18/04/17 15:22 Description: 这个题用并查集做,更好.在练搜索,试试手 本来用的v ...
- ASP.NET Core - Razor 页面简介
简介 随着ASP.NET Core 2 即将来临,最热门的新事物是Razor页面.在之前的一篇文章中,我们简要介绍了ASP.NET Core Razor 页面. Razor页面是ASP.NET Cor ...
- 开源作业调度工具实现开源的Datax、Sqoop、Kettle等ETL工具的作业批量自动化调度
1.阿里开源软件:DataX DataX 是一个异构数据源离线同步工具,致力于实现包括关系型数据库(MySQL.Oracle等).HDFS.Hive.ODPS.HBase.FTP等各种异构数据源之间稳 ...
- UNIX 高手的 10 个习惯
引言 当您经常使用某个系统时,往往会陷入某种固定的使用模式.有时,您没有养成以尽可能最好的方式做事的习惯.有时,您的不良习惯甚至会导致出现混乱.纠正此类缺点的最佳方法之一,就是有意识地采用抵制这些坏习 ...
- DATAGUARD常用管理命令
--DATAGUARD常用管理命令 ----------------------------2014/04/22 备用服务器的管理模式与只读模式 1.1备库启动到管理恢复模式 SQL>shutd ...
- 【Java集合学习】HashMap源码之“拉链法”散列冲突的解决
1.HashMap的概念 HashMap 是一个散列表,它存储的内容是键值对(key-value)映射. HashMap 继承于AbstractMap,实现了Map.Cloneable.java.io ...
- DLL基础
Visual C++在创建DLL导出函数时,可能会对原始的函数名做修改.例如: int WINAPI Add(int nLeft, int nRight) 导出后的函数名称是_Add@8. 下面两种方 ...
- mysql 5.7 怎么修改默认密码、随机密码
当你使用 mysql -u root -p 登陆mysql的时候,提示下方要输入密码.而这个密码不是我们刚刚安装mysql时设置的那个密码.而且安装完mysql 生成的随机密码 那么我们在哪里找到这个 ...