在Linux系统中,系统是通过inode来获得这个文件的信息。在Linux系统中,inode的信息都是封装在stat这个结构体中。可以通过man 2 stat来查看stat的具体结构。从中可以看到包含了文件的UID,GID,大小,以及访问,修改,改变文件状态的时间

struct stat {

dev_t st_dev; /* ID of device containing file */

ino_t st_ino; /* inode number */

mode_t st_mode; /* protection */

nlink_t st_nlink; /* number of hard links */

uid_t st_uid; /* user ID of owner */

gid_t st_gid; /* group ID of owner */

dev_t st_rdev; /* device ID (if special file) */

off_t st_size; /* total size, in bytes */

blksize_t st_blksize; /* blocksize for filesystem I/O */

blkcnt_t st_blocks; /* number of 512B blocks allocated */

/*
Since Linux 2.6, the kernel supports nanosecond

precision
for the following timestamp fields.

For
the details before Linux 2.6, see NOTES. */

struct
timespec st_atim; /* time of last access */

struct
timespec st_mtim; /* time of last modification */

struct
timespec st_ctim; /* time of last status change */

#define
st_atime st_atim.tv_sec /* Backward compatibility */

#define
st_mtime st_mtim.tv_sec

#define
st_ctime st_ctim.tv_sec

};

下面的这个例子打开一个文件并输出文件的统计信息

#include <sys/stat.h>
#include <malloc.h>

char *path="/home/zhf/test1.txt";

void check_file(){
    struct stat *buf=NULL;
    buf=(struct stat *)malloc(sizeof(struct stat));
    stat(path,buf);
    printf("the file size is %ld\n",buf->st_size);
    printf("the user id is %d\n",buf->st_uid);
    printf("the user id is %d\n",buf->st_gid);

}

运行结果

the file size is 7
the user id is 0
the user id is 0

对应的是root用户

root@zhf-maple:/home/zhf# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash

文件夹类型信息包含在stat结构的st_mode成员中,可以用下面的宏来确定文件类型,这些宏参数都是stat结构中的st_mode成员。如果判断为真,则返回1,否则返回0

S_ISREG(): 普通文件

S_ISDIR():目录文件

S_ISCHR(): 字符特殊文件

S_ISBLK():块特殊文件

S_ISFIFO():管道或FIFO

S_ISLNK():符号链接

S_ISSOCK():套接字

前面的check_file添加如下判断就可以进行判断文件是否是一个普通的文件

if (S_ISREG(buf->st_mode)){
        printf("it is a normal file");
    }

在创建文件或者文件夹的时候,创建的文件和文件夹都有三个类别的权限:1 用户的读,写,执行门限 2 同一个组的用户读,写,执行门限 3 其他用户的读,写,执行门限

在st_mode中也包含了这些权限位:

S_IRUSR:用户读

S_IWUSR:用户写

S_IXUSR:用户执行

S_IRGRP:组读

S_IWGRP:组写

S_IXGRP:组执行

S_IROTH:其他读

S_IWOTH:其他写

S_IXOTH :其他执行

那么在创建文件的时候,我们是如何指定这些文件的权限的呢。在手动创建文件的时候,文件的权限取决于umask。文件和文件夹的默认完成权限分别是666和777. 在创建的时候,是采用默认权限减去umask的值。比如如果umask的值是022. 那么创建的文件和文件夹的权限分别是644和755。测试如下

root@zhf-maple:/home/zhf# touch mask.txt

root@zhf-maple:/home/zhf# ls -al mask.txt

-rw-r--r-- 1 root root 0 4月  20 16:58 mask.txt

root@zhf-maple:/home/zhf# umask

0022

在用代码创建的时候同样也可以使用umask函数。在这里首先定义了RWRWRW, 权限是666. 在umask中屏蔽了S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH。因此最终创建的文件应该是600.

#define RWRWRW (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOT

void mask_function_try(){

int mode;

char *path="/home/zhf/mask.txt";

umask(S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);

creat(path,RWRWRW);

}

实际结果:

root@zhf-maple:/home/zhf# ls -al | grep mask.txt

-rw-------  1 root         root         0 4月  20 17:22 mask.txt

下面来看下具体操作文件的操作。首先来看下修改文件属性。系统提供了chown,fchown来修改指定文件的所有者以及用户组。函数原型如下:调用成功时,返回值为0,失败返回-1.并设置相应的errno值。

int
chown(const char *pathname, uid_t owner, gid_t group);

int
fchown(int fd, uid_t owner,gid_t group);

两个函数不同的是chown参数pathname是文件的路径,而fchown中fd是文件的描述符

其中uid_t和gid_t如果是-1的话就代表不改变。我们来看一个例子。

/home/zhf/zhf下有个文件test.png
用户和用户组分别属于zhf.
现在我们将用户改为zhf_test

-rw-rw-r--
1 zhf zhf 38844 Aug 6 15:28 test.png

查看zhf_test用户的用户ID和用户组ID,分别是1100和1101.

root@zhf-linux:/home/zhf/zhf#
cat /etc/passwd | grep zhf_test

zhf_test:x:1100:1101::/home/zhf_test:

修改代码如下:

#include
<sys/types.h>

#include
<unistd.h>

#include
<stdio.h>

#include
<stdlib.h>

void
change_file_owner()

{

char
*path="/home/zhf/zhf/test.png";

chown(path,1100,-1);

}

void
main()

{

change_file_owner()

}

执行过后查看test.png发现用户名已经被修改为zhf_test.

-rw-rw-r--
1 zhf_test zhf 38844 Aug 6 15:28 test.png

来看下fchown的用法。fchown是通过文件属性来修改文件的。文件属性通过open函数来获得。open函数返回一个整数的文件描述符。代码如下,
O_RDONLY代表的是以只读的方式打开文件。具体的打开方式可以通过man
2 open来查看

void
change_file_owner_by_fchown()

{

int
fd;

fd=open("/home/zhf/zhf/test.png",O_RDONLY);

fchown(fd,1100,-1);

close(fd);

}

改变文件的名称:

修改文件名称采用rename函数

int
rename(const char *oldpath, const char *newpath)

两个参数都为指针,第一个指向原来文件的名称,第二个指向新的文件。调用成功返回0。否则函数返回-1

void
change_file_name()

{

char
*oldname="/home/zhf/zhf/test.png";

char
*newname="/home/zhf/zhf/test_rename.png";

rename(oldname,newname);

}

获取文件信息:

采用stat函数。int
stat(const char *path, struct stat *buf)

path表示指向需要获取信息的文件的路径名

参数buf表示指向一个stat结构体类型的指针。

注意打印buf.st_size的时候需要用长整型。因为st_size是off_t结构,也就是长整型的数值

void
get_file_informaton()

{

struct
stat buf;

stat("file_try.c",&buf);

printf("file_try
size=%ld\n",buf.st_size);

printf("file_try
UID=%d\n",buf.st_uid);

}

否则会出现如下的警告:

file_try.c:32:9:
warning: format ‘%d’ expects argument of type ‘int’, but
argument 2 has type ‘__off_t {aka long int}’ [-Wformat=]

linux c编程:文件的操作的更多相关文章

  1. Linux系统编程--文件IO操作

    Linux思想即,Linux系统下一切皆文件. 一.对文件操作的几个函数 1.打开文件open函数 int open(const char *path, int oflags); int open(c ...

  2. Linux系统编程@文件操作(一)

    只总结了部分常用的内容,详细内容参考<UNIX环境高级编程>及相关书籍. Linux中文件编程可以使用两种方法 Linux系统调用(依赖于系统) C语言库函数(不依赖于系统) Linux系 ...

  3. Linux学习记录--文件IO操作相关系统编程

    文件IO操作相关系统编程 这里主要说两套IO操作接口,各自是: POSIX标准 read|write接口.函数定义在#include<unistd.h> ISO C标准 fread|fwr ...

  4. linux系统编程--文件IO

    系统调用 什么是系统调用: 由操作系统实现并提供给外部应用程序的编程接口.(Application Programming Interface,API).是应用程序同系统之间数据交互的桥梁. C标准函 ...

  5. c#基础语言编程-文件流操作

    引言 在System.IO 命名空间下提供了一系列的类,我们可以通过相应的类进行文件.目录.数据流的操作. 1.File类:提供用于创建.复制.删除.移动和打开文件的静态方法.File类 2.File ...

  6. grep sed awk 3个Linux中对文件内容操作的命令

    在学习Linux命令中,发现3个有关于文件内容操作的命令grep,sed和awk,在这里简单汇总这3个命令主要作用,在实际中找到最合适的情景应用,详细用法可以参考其他文章. 1.grep命令 主要作用 ...

  7. Linux 目录和文件的操作

    整理常用的linux命令,关于目录和文件的操作,用于巩固记忆,以备不时之需. [root@localhost ~] root:当前用户 localhost:主机名 ~:当前所在位置 符号#:管理员 符 ...

  8. linux中普通的文件查看操作(cat、more、less、head、tail)

    cat:基本是最常用的查看文件内容的linux命令. more 也是用来查看一个文件的内容.当文件内容太多,一屏幕不能占下,而你用cat肯定是看不前面的内容的,那么使用more就可以解决这个问题了.当 ...

  9. Linux shell 编程文件比较

    文件比较允许你测试Linux 文件系统上文件和目录的状态 比较 描述 -d file  检查file是否存在并是一个目录 -e file 检查file是否存在 -f file 检查file是否存在并是 ...

  10. Linux系统编程--文件描述符的复制dup()和dup2()【转】

    本文转载自:http://blog.csdn.net/tennysonsky/article/details/45870459 dup() 和 dup2() 是两个非常有用的系统调用,都是用来复制一个 ...

随机推荐

  1. 生成唯一标识符 ,通用唯一标识符 UUID

    import java.util.UUID; /** * UUID生成工具 * */ public final class UuidGenUtils { /** * 生成一个UUID串(32个字符,其 ...

  2. 手把手教你构建 C 语言编译器

    http://lotabout.me/2015/write-a-C-interpreter-1/

  3. Autolayout 03

    Debugging in Code 有两个调试layout问题的阶段. 1. Map from “this view is in the wrong place” to “this constrain ...

  4. python 制作wordcloud词云

    pip install wordcloud 需要用到numpy  pillow matplotlib 安装完成以后 wordcloud_cli --text in.txt --imagefile ou ...

  5. suid sgid sbit chattr lsattr find

    suid 一般用于二进制可执行文件不可用于shell脚本和目录,suid代表当用户执行此二进制文件时,暂时具有此文件所有者的权限 chmod 4xxx binfile sgid 一般用于目录,sgid ...

  6. merge-sorted-array——合并两个有序数组

    Given two sorted integer arrays A and B, merge B into A as one sorted array. Note: You may assume th ...

  7. c# out ref

    out 关键字会导致参数通过引用来传递.这与 ref 关键字类似,不同之处在于 ref 要求变量必须在传递之前进行初始化.若要使用 out 参数,方法定义和调用方法都必须显式使用 out 关键字.例如 ...

  8. java 中 instanceof 和 isInstance区别

    两者的功能是等价的.区别: 1.instanceof 是一个操作符(类似new, ==等): 使用方法: if (ins instanceof String) { //logic } 2.isInst ...

  9. &lt;LeetCode OJ&gt; 189. Rotate Array

    189. Rotate Array Total Accepted: 55073 Total Submissions: 278176 Difficulty: Easy Rotate an array o ...

  10. jenkins 构建一个前端web项目

    Jenkins发布web前端代码 “系统管理”“管理插件”“已安装” 检查是否有“Git plugin”和“Publish Over SSH”两个插件,如果没有,则需点击“可选插件”,找到它并安装 ...