`
灵动的水
  • 浏览: 194605 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

文件操作经典概括

阅读更多
OS.h  分类: C++ 2009-07-19 12:31

#ifndef ICE_PATCH2_OS_H
#define ICE_PATCH2_OS_H

#include <Ice/Config.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>

#ifndef ICE_PATCH2_API
#   ifdef ICE_PATCH2_API_EXPORTS
#       define ICE_PATCH2_API ICE_DECLSPEC_EXPORT
#   else
#       define ICE_PATCH2_API ICE_DECLSPEC_IMPORT
#   endif
#endif

namespace OS
{

#ifdef _WIN32

typedef struct _stat structstat;
#ifdef _MSC_VER
#   define O_RDONLY _O_RDONLY
#   define O_BINARY _O_BINARY

#   define S_ISDIR(mode) ((mode) & _S_IFDIR)
#   define S_ISREG(mode) ((mode) & _S_IFREG)
#endif

#else

// linux  则定义 stat 结构 为structstat 类型,  O_BINARY为0

typedef struct stat structstat;

#   define O_BINARY 0

#endif

// BUGFIX: aCC errors if this is stat.

ICE_PATCH2_API int osstat( const std::string&, structstat* );

ICE_PATCH2_API int remove( const std::string& );

ICE_PATCH2_API int rename( const std::string&, const std::string& );

ICE_PATCH2_API int rmdir( const std::string& );

ICE_PATCH2_API int mkdir( const std::string&, int );

ICE_PATCH2_API FILE* fopen( const std::string&, const std::string& );

ICE_PATCH2_API int open( const std::string&, int );

ICE_PATCH2_API int getcwd( std::string& ) ;

}

#endif




#include <IceUtil/DisableWarnings.h>
#include <OS.h>
#include <IceUtil/Unicode.h>

#ifdef __BCPLUSPLUS__
#  include <dir.h>
#  include <io.h>
#endif

using namespace std;
using namespace OS;

#ifdef _WIN32


#else


//linux 调用stat函数将path指定的文件结构信息,保存到buf中

/*


表头文件:    #include <sys/stat.h>
#include <unistd.h>
定义函数:    int stat(const char *file_name, struct stat *buf);
函数说明:    通过文件名filename获取文件信息,并保存在buf所指的结构体stat中
返回值:     执行成功则返回0,失败返回-1,错误代码存于errno

错误代码:
ENOENT         参数file_name指定的文件不存在
ENOTDIR        路径中的目录存在但却非真正的目录
ELOOP          欲打开的文件有过多符号连接问题,上限为16符号连接
EFAULT         参数buf为无效指针,指向无法存在的内存空间
EACCESS        存取文件时被拒绝
ENOMEM         核心内存不足
ENAMETOOLONG   参数file_name的路径名称太长


#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>

int main() {
struct stat buf;
stat("/etc/hosts", &buf);
printf("/etc/hosts file size = %d\n", buf.st_size);
}


-----------------------------------------------------
struct stat {
dev_t         st_dev;       //文件的设备编号
ino_t         st_ino;       //节点
mode_t        st_mode;      //文件的类型和存取的权限
nlink_t       st_nlink;     //连到该文件的硬连接数目,刚建立的文件值为1
uid_t         st_uid;       //用户ID
gid_t         st_gid;       //组ID
dev_t         st_rdev;      //(设备类型)若此文件为设备文件,则为其设备编号
off_t         st_size;      //文件字节数(文件大小)
unsigned long st_blksize;   //块大小(文件系统的I/O 缓冲区大小)
unsigned long st_blocks;    //块数
time_t        st_atime;     //最后一次访问时间
time_t        st_mtime;     //最后一次修改时间
time_t        st_ctime;     //最后一次改变时间(指属性)
};

先前所描述的st_mode 则定义了下列数种情况:
S_IFMT   0170000    文件类型的位遮罩
S_IFSOCK 0140000    scoket
S_IFLNK 0120000     符号连接
S_IFREG 0100000     一般文件
S_IFBLK 0060000     区块装置
S_IFDIR 0040000     目录
S_IFCHR 0020000     字符装置
S_IFIFO 0010000     先进先出

S_ISUID 04000     文件的(set user-id on execution)位
S_ISGID 02000     文件的(set group-id on execution)位
S_ISVTX 01000     文件的sticky位

S_IRUSR(S_IREAD) 00400     文件所有者具可读取权限
S_IWUSR(S_IWRITE)00200     文件所有者具可写入权限
S_IXUSR(S_IEXEC) 00100     文件所有者具可执行权限

S_IRGRP 00040             用户组具可读取权限
S_IWGRP 00020             用户组具可写入权限
S_IXGRP 00010             用户组具可执行权限

S_IROTH 00004             其他用户具可读取权限
S_IWOTH 00002             其他用户具可写入权限
S_IXOTH 00001             其他用户具可执行权限

上述的文件类型在POSIX中定义了检查这些类型的宏定义:
S_ISLNK (st_mode)    判断是否为符号连接
S_ISREG (st_mode)    是否为一般文件
S_ISDIR (st_mode)    是否为目录
S_ISCHR (st_mode)    是否为字符装置文件
S_ISBLK (s3e)        是否为先进先出
S_ISSOCK (st_mode)   是否为socket


若一目录具有sticky位(S_ISVTX),则表示在此目录下的文件只能被该文件所有者、
此目录所有者或root来删除或改名。

-----------------------------------------------------
struct statfs {
long    f_type;          //文件系统类型
long    f_bsize;         //块大小
long    f_blocks;        //块多少
long    f_bfree;         //空闲的块
long    f_bavail;        //可用块
long    f_files;         //总文件节点
long    f_ffree;         //空闲文件节点
fsid_t f_fsid;           //文件系统id
long    f_namelen;       //文件名的最大长度
long    f_spare[6];      //spare for later
};



stat、fstat和lstat函数(UNIX)


#include<sys/types.h>
#include<sys/stat.h>
int stat(const char *restrict pathname, struct stat *restrict buf);
提供文件名字,获取文件对应属性。感觉一般是文件没有打开的时候这样操作。
int fstat(int filedes, struct stat *buf);
通过文件描述符获取文件对应的属性。文件打开后这样操作
int lstat(const char *restrict pathname, struct stat *restrict buf);
连接文件

三个函数的返回:若成功则为0,若出错则为-1
给定一个pathname,stat函数返回一个与此命名文件有关的信息结构,
fstat函数获得已在描述符filedes上打开的文件的有关信息。lstat函数类似于stat,
但是当命名的文件是一个符号连接时,lstat返回该符号连接的有关信息,
而不是由该符号连接引用的文件的信息。

第二个参数是个指针,它指向一个我们应提供的结构。这些函数填写由buf指向的结构。
该结构的实际定义可能随实现而有所不同,但其基本形式是:

struct stat{
mode_t st_mode;   /*file tpye &mode (permissions)
ino_t st_ino;     /*i=node number (serial number)
dev_t st_rdev;   /*device number for special files
nlink_t st_nlink; /*number of links
uid_t    st_uid; /*user id of owner
gid_t    st_gid; /*group ID of owner
off_t   st_size; /*size in bytes for regular files
time_t st_atime; /*time of last access
time_t st_mtime; /*time of last modification
time_t st_ctime; /*time of last file status change
long st_blksize; /*best I/O block size 
long st_blocks; /*number of 512-byte blocks allocated
};
注意,除最后两个以外,其他各成员都为基本系统数据类型。
我们将说明此结构的每个成员以了解文件属性。

使用stat函数最多的可能是ls-l命令,用其可以获得有关一个文件的所有信息。



1 函数都是获取文件(普通文件,目录,管道,socket,字符,块()的属性。
函数原型#include <sys/stat.h>

int stat(const char *restrict pathname, struct stat *restrict buf);提供文件名字,
获取文件对应属性。
int fstat(int filedes, struct stat *buf);通过文件描述符获取文件对应的属性。
int lstat(const char *restrict pathname, struct stat *restrict buf);连接文件描述命,
获取文件属性。2 文件对应的属性struct stat {
mode_t     st_mode;       //文件对应的模式,文件,目录等
ino_t      st_ino;       //inode节点号
dev_t      st_dev;        //设备号码
dev_t      st_rdev;       //特殊设备号码
nlink_t    st_nlink;      //文件的连接数
uid_t      st_uid;        //文件所有者
gid_t      st_gid;        //文件所有者对应的组
off_t      st_size;       //普通文件,对应的文件字节数
time_t     st_atime;      //文件最后被访问的时间
time_t     st_mtime;      //文件内容最后被修改的时间
time_t     st_ctime;      //文件状态改变时间
blksize_t st_blksize;    //文件内容对应的块大小
blkcnt_t   st_blocks;     //伟建内容对应的块数量
};可以通过上面提供的函数,返回一个结构体,保存着文件的信息。


*/

int
OS::osstat( const string& path, structstat* buf )
{
return ::stat( path.c_str(), buf );
}

/*

remove函数的功能是删除一个文件。它的一般格式为:
remove(const char * filename);
remove函数也是一个宏,可以删除filename(文件名)指定的文件。
如果文件已经打开,则必须将该文件关闭才能够删除。如果调用成功,
返回0,否则返回-1,并置全局变量errno为ENOENT(没有此文件或目录)
或EACCES(无此权限)。

NAME
       rename - change the name or location of a file

SYNOPSIS
       #include <stdio.h>

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

DESCRIPTION
       rename() renames a file, moving it between directories if required.

       Any other hard links to the file (as created using link(2)) are unaffected.

       If newpath already exists it will be atomically replaced (subject
    to a few conditions; see ERRORS below),
       so that there is no point at which another process attempting to
    access newpath will find it missing.

The rename function causes the file whose name is the string pointed to by old to be
henceforth known by the name given by the string pointed to by new. The file named
old is no longer accessible by that name.
If a file named by the string pointed to by new exists prior to the call to
the rename function, the behavior is implementation-defined.



ISO C99 p267
man 2 rename
oldpath and newpath are not on the same mounted filesystem. 
(Linux permits  a  filesystem  to  be
              mounted at multiple points, but rename(2) does not work
     across different mount points, even if the
              same filesystem is mounted on both.)


rename(更改文件名称或位置) 
相关函数  link,unlink,symlink
表头文件  #include<stdio.h>
定义函数  int rename(const char * oldpath,const char * newpath);
函数说明  rename()会将参数oldpath 所指定的文件名称改为参数newpath所指的文件名称。
若newpath所指定的文件已存在,则会被删除。
返回值  执行成功则返回0,失败返回-1,错误原因存于errno

范例  设计一个DOS下的rename指令rename 旧文件名新文件名


mkdir和rmdir函数.
    int mkdir(const char*pathname,mode_t mode);//创建一个空目录
    int rmdir(const char *pathname);           //删除一个空目录,不能删除有文件目录
  

读目录
    对于某个目录具有访问权限的任一用户都可以读该目录,但是,为了防止文件系统
产生混乱,只有内核才能写目录.这里又有一个新头文件出现<dirent.h>
    DIR* opendir(const char *pathname);//成功返回指针,出错返回NULL
    struct dirent *readdir(DIR *dp);
    void rewinddir(DIR *dp);
    int closedir(DIR *dp);
    long telldir(DIR *dp);
    void seekdir(DIR *dp,long loc);

    struct dirent        //来自/usr/include/bits/dirent.h
    {
#ifndef __USE_FILE_OFFSET64
        __ino_t d_ino;
        __off_t d_off;
#else
        __ino64_t d_ino;              //i_node节点号
        __off64_t d_off;
#endif
        unsigned short int d_reclen;
        unsigned char d_type;
        char d_name[256];         /*We must not include limits.h //目录名
    }

   DIR结构是内核用的,对用户不公开使用.


一、获取当前工作目录函数-getcwd
头文件:<unistd.h>
函数形式:char* getcwd(char *buffer,size_t size)
返回值:成功返回当前工作目录的字符串指针
              失败返回NULL
              设置errno


错误信息:
EINVAL:size参数为0或者buff不是空指针;
ERANGE:size参数小于当前工作目录的长度,需要分配更大的内存
EACCES:权限不足,没有读或者搜索文件名称的权限
          
二、获得系统目录最大长度-pathconf
头文件:unistd.h
函数形式:long pathconf(char *path,int name)
返回值:成功返回目录长度的极限值
              失败返回-1
              设置errno

//name:pathconf_exam.cxx
#include<unistd.h>
#include<iostream.h>

int main(void)
{
    long cur_work_len;
    char*  cur_work_dir;

//获得目录最大长度
if((cur_work_len=pathconf(".",_PC_PATH_MAX))==-1)
{
    perror("Could not get current working directory length!");
    return 1;
}
std::cout<<"Current work length is "<<cur_work_len<<std::endl;

//根据获得的目录的最大长度,分配内存
if((cur_work_dir=(char*)malloc(cur_work_len))==NULL)
{
    perror("Could not allocate memory for the directory!");
    return 1;
}

//获得当前的工作目录
if (getcwd(cur_work_dir,cur_work_len)==NULL)
{
    perror("Could not get current working directory!");
    return 1;
}

std::cout<<"Current working directory is "<<cur_work_dir<<std::endl;
return 0;
}
程序执行结果:
guocheng@guocheng-desktop:~/test/dir_exam/pathconf$ g++ -o pathconf_exam pathconf_exam.cxx
guocheng@guocheng-desktop:~/test/dir_exam/pathconf$ ./pathconf_exam
Current work length is 4096
Current working directory is /home/guocheng/test/dir_exam/pathconf

三、更改当前工作目录-chdir和fchdir

头文件:unisd.h
函数形式:int chdir(const char* path)
                 int fchdir(fd)
返回值:成功0
              失败-1
              设置errno
说明:chdir函数的参数是指向目录的字符串指针,成功的前提是程序有所搜整个目录的权限,fchdir调用的参数是目录的文件描述符,其他与chdir相同。

按照上面的例子进行修改。
//name:chdir_exam.cxx
#include<unistd.h>
#include<iostream.h>

int main(void)
{
    long cur_work_len;
    char*  cur_work_dir;

//获得目录最大长度
if((cur_work_len=pathconf(".",_PC_PATH_MAX))==-1)
{
    perror("Could not get current working directory length!");
    return 1;
}
std::cout<<"Current work length is "<<cur_work_len<<std::endl;

//根据获得的目录的最大长度,分配内存
if((cur_work_dir=(char*)malloc(cur_work_len))==NULL)
{
    perror("Could not allocate memory for the directory!");
    return 1;
}

//获得当前的工作目录
if (getcwd(cur_work_dir,cur_work_len)==NULL)
{
    perror("Could not get current working directory!");
    return 1;
}

std::cout<<"Current working directory is "<<cur_work_dir<<std::endl;

//修改当前目录至上级目录
if(chdir("..")==-1)
{
    perror("Could not get current working directory!");
    return 1;
}

//获得当前的工作目录
if (getcwd(cur_work_dir,cur_work_len)==NULL)
{
    perror("Could not get current working directory!");
    return 1;
}

std::cout<<"Current working directory is "<<cur_work_dir<<std::endl;
return 0;
}
执行结果
guocheng@guocheng-desktop:~/test/dir_exam/chdir$ ./chdir_exam
Current work length is 4096
Current working directory is /home/guocheng/test/dir_exam/chdir
Current working directory is /home/guocheng/test/dir_exam


四、创建和删除工作目录-mkdir和rmdir
头文件:sys/stat.h    sys/types.h
函数形式:int mkdir(const char* pathname,mode_t mode);
返回值:成功0,失败-1,设置errno
说明:创建的目录的权限由mode、-umask和0777的与值来决定。
下面是实力,在/tmp/guocheng/的目录下创建目录yu,具体代码实现如下:
//mkdir_exam.cxx
#include <sys/stat.h>
#include <sys/types.h>
#include <iostream.h>
int main(void)
{
char* pathname="/tmp/guocheng/yu";
if(mkdir(pathname,0700)==-1)
{
    perror("Could not create the direcotry!");
    return 1;
}
return 0;
}
函数:int rmdir(const char* pathname);
返回值:成功0,失败-1,设置errno。


1、linux文件的实现
索引结点结构(inode)在linxu系统中实现文件的存储和相关信息的保存,每个inode中存储有文件的属性、访问权限以及文件数据块的存储位置。对linux系统而言,inode是文件系统定位文件的基本途径。
左图描述了inode的结构:图中前四项统称为文件的描述信息,其他的信息均为定位文件数据的指针。
文件描述信息主要包括:
Mode:包含有inode的描述内容和用户访问权限;
Owner Infomation:文件或目录所有者的信息,包括所属组信息;
Size:用于记录文件的大小,以字节为单位;
Timesstamps:时间戳,用于记录inode的创建时间及最后的修改时间;
定位文件数据的指针主要包括以下几种:
直接块指针:前12个,直接指向数据块
间接块指针:第13个,指向含有块指针的数据块
双重间接块指针:第14个
三重间接块指针:第15个
inode共有15个块指针的数组,前12为直接指向数据快的指针,第13个是间接数据块指针,指向含有数据块指针的数据块,14和15一次类推。
假设每个指向的数据块的大小是1024字节,每个指针是32位(4字节),下面进行计算文件容量。
直接块指针:12个X1024字节=12K;
间接块指针:1个X(1024字节/4字节)X1024字节=246K;
双重间接块指针:1个X(1024字节/4字节)X(1024字节/4字节)X1024字节=65536K
三重间接块指针:1个X(1024字节/4字节)X(1024字节/4字节)X(1024字节/4字节)1024字节=16777216K,即16G;

2、文件描述符与文件指针
在linux系统中,统一了文件和设备的操作,提供了open、read、close等函数,使用文件描述符来对文件进行操作。文件描述符是一个int类型的数值,在使用open函数操作文件时返回的。
如果某个进程使用open函数打开了一个文件,通过fork函数创建当前进程的子进程,则子进程会继承父进程的环境和上下文的大部分内容,包括已经打开的文件的描述符信息,父进程和子进程将共享相同的文件偏移量。
例程:
#include <stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>



int main(void)

{

//定义字符类型名字为test的字符变量

char test;



//fd用于保存打开文件的文件描述符

int fd;

//使用open函数以只读方式打开名称为test.dat的文件

//如果打开失败则给出相关的失败信息,程序返回

if((fd=open("test.dat",O_RDONLY))==-1)

{

    perror("Can not open the test.dat file!");

    return 1;

}



//使用fork函数产生子进程,如果产生失败给出失败信息,程序返回

if(fork()==-1)

{

    perror("Can not create the child process!");

    return 1;

}



//读取test.dat文件中的一个字符,将其保存在名称为test的字符变量中

read(fd,&test,1);



//输出运行结果,函数getpid会获得进程的进程号

printf("Process ID:%ld read the chatacter :%c\n",(long)getpid(),test);



//关闭文件,注意这里实际会关闭两次

//父子进程将分别执行一次关闭动作

close(fd);

return 0;

}

程序执行结果如下:
guocheng@guocheng-desktop:~/test/fd_exam$ cat test.dat

abcdefgh

guocheng@guocheng-desktop:~/test/fd_exam$ gcc -o fd_exam fd_exam.c

guocheng@guocheng-desktop:~/test/fd_exam$ ./fd_exam

Process ID:7673 read the chatacter :a

Process ID:7672 read the chatacter :b

父进程和子进程分别读取了一个字符,父子进程共享相同的文件描述符,因此父子进程读取的字符是不相同的。

3、文件的访问权限
文件的权限在文件inode的Mode字段的0-8来描述,统称用三位八进制表示。

4、获取文件信息函数
头文件:<sys/types.h>   <sys/stat.h>    <unistd.h>
函数形式:int stat(const char *path,strct stat *buf);
       int fstat(int filedes,struct stat *buf);
       int lstat(const chat *path,strct stat *buf);
返回值:成功0,失败-1,设置errno;
参数:结构体stat说明文件信息,具体含有不做解释。
struct stat
{
dev_t     st_dev     ID of device containing file
ino_t     st_ino     file serial number
mode_t    st_mode    mode of file (see below)
nlink_t   st_nlink   number of links to the file
uid_t     st_uid     user ID of file
gid_t     st_gid     group ID of file
dev_t     st_rdev    device ID (if file is character or block special)
off_t     st_size    file size in bytes (if file is a regular file)
blksize_t st_blksize    a filesystem-specific preferred I/O block size for
                        this object.  In some filesystem types, this may
                        vary from file to file
blkcnt_t  st_blocks  number of blocks allocated for this object

time_t    st_atime   time of last access
time_t    st_mtime   time of last data modification
time_t    st_ctime   time of last status change
}
区别:stat和lstat的区别是当目标是符号连接时,lstat返回的是符号连接的inode信息而不是符号连接指向的文件信息,fstat和stat的区别是第一个参数不同,fstat使用文件描述符做参数。
函数例程:
#include <stdio.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <unistd.h>



int main(int argc,char* argv[1])

{

//定义类型为stat的机构体file_stat,用于保存获得的文件信息

struct stat file_stat;



//main带参数运行,程序名称是一个参数

//判断程序是否带有一个参数执行,共两个参数,如果不是给出提示

//程序结束运行

if(argc!=2)

{

    printf("Usage :%s filename!\n",argv[0]);

    return 1;

}



//调用stat函数,如果出现错误给出错误信息,程序退出

if(stat(argv[1],&file_stat)==-1)

{

    perror("Can not get the information of the file!\n");

    return 1;

}



//使用POSIX中定义的宏判断是否是常规文件

if(S_ISREG(file_stat.st_mode))

    printf("%s is Regular file,Judeged by S_ISREG\n",argv[1]);



//通过st_mode与S_IFREG的位运算判断是否是目录

if(file_stat.st_mode & S_IFREG)

    printf("%s is a Regular File,Judeged by bits calculate  S_IFREG\n",argv[1]);



//通过S_ISDIR宏判断是否是目录

if(S_ISDIR(file_stat.st_mode))

    printf("%s is a Directory,Judeged by S_ISDIR\n",argv[1]);



//通过st_mode与S_IFDIR的位运算判断是否是目录

if(file_stat.st_mode & S_IFDIR)

    printf("%s is a Directory,Judeged by bits calculate  S_IFDIR\n",argv[1]);



//输出file_stat中的其他文件信息

printf("Ower ID:%d,Group ID:%d\n",file_stat.st_uid,file_stat.st_gid);

printf("Permission:%o\n",file_stat.st_mode & 0x1ff);

printf("Last Access Time:%15s\n",ctime(&file_stat.st_atime));

printf("Last Modification Time:%15s\n",ctime(&file_stat.st_mtime));

printf("Last Status Change Time:%15s\n",ctime(&file_stat.st_ctime));



return 0;

}
程序运行结果:
guocheng@guocheng-desktop:~/test/stat_exam$ ls

a.out  stat_exam.c  stat_exam.c~  test

guocheng@guocheng-desktop:~/test/stat_exam$ ./a.out stat_exam.c

stat_exam.c is Regular file,Judeged by S_ISREG

stat_exam.c is a Regular File,Judeged by bits calculate  S_IFREG

Ower ID:1000,Group ID:1000

Permission:644

Last Access Time:Sun Mar  1 00:32:05 2009


Last Modification Time:Sun Mar  1 00:30:51 2009


Last Status Change Time:Sun Mar  1 00:30:51 2009

guocheng@guocheng-desktop:~/test/stat_exam$ ./a.out test/

test/ is a Directory,Judeged by S_ISDIR

test/ is a Directory,Judeged by bits calculate  S_IFDIR

Ower ID:1000,Group ID:1000

Permission:755

Last Access Time:Sun Mar  1 00:25:37 2009


Last Modification Time:Sun Mar  1 00:25:36 2009


Last Status Change Time:Sun Mar  1 00:25:36 2009




5、修改文件权限函数
头文件:    <sys/stat.h>    <sys/types.h>
函数形式:int chmod(const char *path,mode_t mode);
       int fchmod(int filedes,mode_t mode);
返回值:成功0,失败-1,设置errno;
两个函数的区别在第一个参数,使用宏定义组合设置文件的权限。
例程:
#include <sys/types.h>

#include <sys/stat.h>

#include <stdio.h>



int main(int argc,char* argv[])

{

if(argc!=2)

{

    printf("Error!");

    return 1;

}



//修改文件权限至r--r--r-x

if(chmod(argv[1],S_IRUSR | S_IRGRP | S_IROTH | S_IXOTH)<0)

{

    perror("Can not modify the permission of the file !");

    return 1;

}



return 0;

}
执行结果:
guocheng@guocheng-desktop:~/test/chmod_exam$ ls -al test

---------- 1 guocheng guocheng 0 2009-03-01 00:50 test

guocheng@guocheng-desktop:~/test/chmod_exam$ ./a.out test

guocheng@guocheng-desktop:~/test/chmod_exam$ ls -al test

-r--r--r-x 1 guocheng guocheng 0 2009-03-01 00:50 test

6、修改文件拥有者函数
头文件:    <sys/stat.h>    <sys/types.h>
函数形式:int chown(const char *path,uid_t owner,gid_t,group);
       int fchown(int fd,uid_t owner,gid_t,group);
       int lchown(const char *path,uid_t owner,gid_t,group);
返回值:成功0,失败-1,设置errno;

7、Umask函数
头文件:    <sys/stat.h>    <sys/types.h>
函数形式:mode_t umask(mode_t mask);
返回值:总是执行成功返回修改前的umask值

#include <sys/stat.h>

#include <sys/types.h>

#include <fcntl.h>

#include <stdio.h>



int main(void)

{

int fd1,fd2;

struct stat file_stat;



fd1=open("test",O_CREAT | O_RDWR,0777);

if(fd1<0)

{

    perror("Can not create the test file!");

    return 1;

}

close(fd1);

if(stat("test",&file_stat)==-1)

{

    perror("Can not get the information fo the test file!");

    return 1;

}

printf("Permission is %o\n",file_stat.st_mode & 0x1ff);



//修改umask值077

umask(S_IWGRP | S_IRGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH);



fd2=open("test1",O_CREAT | O_RDWR,0777);

if(fd2<0)

{

    perror("Can not create the test1 file!");

    return 1;

}

close(fd2);

if(stat("test1",&file_stat)==-1)

{

    perror("Can not get the information fo the test1 file!");

    return 1;

}

printf("Permission is %o\n",file_stat.st_mode & 0x1ff);



return 0;

}
执行结果:
guocheng@guocheng-desktop:~/test/umask_exam$ vi umask_exam.c

guocheng@guocheng-desktop:~/test/umask_exam$ gcc umask_exam.c

guocheng@guocheng-desktop:~/test/umask_exam$ ./a.out

Permission is 755

Permission is 700



分享到:
评论

相关推荐

    随机文件操作

    在编程领域,随机文件操作是处理大量数据时常用的一种技术,尤其在需要持久化存储对象或结构化数据时。在给定的场景中,我们有一个`Employee`类,包含编号、姓名、年龄和工资等数据成员。这个任务要求在当前工作目录...

    操作系统实验资料 --进程管理与调度的模拟※ 文件系统模拟

    文件系统是操作系统中用于组织、存储和检索文件的组件。在这个实验中,虽然没有详细展开,但我们可以假设学生需要理解文件的创建、删除、读写操作,以及目录结构的管理。文件系统模拟可能涉及文件的i-node(用于存储...

    数据库系统概括答案

    DBMS是独立于操作系统的软件,但数据库中数据的组织和存储是通过操作系统中的文件系统来实现的。 适合用文件系统和数据库系统的应用例子 适用于文件系统而不是数据库系统的应用例子包括数据的备份、软件或应用程序...

    经典数据库学习资料,概括全面

    总之,这个"经典数据库学习资料"压缩包,尤其是包含的DBF文件,是学习数据库原理和技术的一个好起点。通过深入研究DBF格式,你可以更好地理解和掌握数据库的本质,为未来在更复杂的数据库系统中工作打下坚实的基础。

    dos操作系统的简述

    在DOS环境下,用户通过命令行界面进行操作,例如管理文件、设备等。DOS支持一系列内置命令,如COPY、DEL、DIR等,这些命令帮助用户执行基本的文件管理和系统维护任务。 #### 二、DOS的发展历程 自1981年首次发布...

    WilViewer_wil文件编辑器源码示例_wil文件编辑_wil源码_wil文件编辑器_

    2. **wil文件编辑**:明确了主要功能是对.WIL文件进行编辑操作。 3. **wil源码**:指出该编辑器的实现代码可供学习和使用。 4. **wil文件编辑器**:概括了整个软件的核心作用,即用于.WIL文件的编辑。 **压缩包子...

    西门子G120变频器GSD文件

    在电视不就行概括地讲风华高科大家好附件适当放宽蝴蝶飞过华东师范空间规划地方就会感到很烦,这部分描述可能是一段非相关或者错误的信息,因为其内容与西门子G120变频器或GSD文件本身没有直接关联。可能是文本输入...

    意天文件恢复大师

    ‘意天文件恢复大师’是一款Windows操作系统下的文件恢复软件 【基本介绍】  数据恢复。‘意天文件恢复大师’是一款Windows操作系统下的文件恢复软件,其软件精小而功能强大。 【软件特色】 1、当您不小心删除...

    寻找文件例子。(4KB)...

    标签“文件处理”和“源代码”是对内容的精炼概括,表明这个压缩包包含的代码着重于文件操作,并且可以被开发者学习和参考。 根据压缩包子文件的文件名称列表,我们可以推断出以下内容: 1. SEEK.FRM:这是一个VB...

    超好用的文本文件合并器 txt文件

    同时,理解如何在Windows操作系统中进行文件操作,例如浏览文件夹、复制/移动文件等,也是使用此类工具的前提。对于企业或专业用户,这样的工具可以极大地提高工作效率,减少手动操作带来的错误。

    (新建 WinRAR 压缩文件.rar

    【标题】"新建 WinRAR 压缩文件.rar" 提示我们这可能是一个...以上就是 WinRAR 相关的知识点,虽然给定的文件描述和标签没有提供太多具体信息,但通过 WinRAR 的功能和特性,我们可以理解如何管理和操作此类压缩文件。

    JAVA 创建Shape文件。并在文件中添加一条折线

    9. **异常处理**:在进行文件操作时,必须处理可能出现的异常,如`FileNotFoundException`、`IOException`等,确保程序的健壮性。 10. **测试与调试**:开发者可能分享了如何测试和调试代码的建议,以确保Shape文件...

    Redhat Linux操作系统下常用服务概括介绍

    "Redhat Linux操作系统下常用服务概括介绍" Redhat Linux 操作系统是一个流行的开源操作系统,它提供了许多有用的服务来提高系统的功能和安全性。下面是 Redhat Linux 操作系统下常用服务的概括介绍: 1. aep1000/...

    文件系统设计与模拟实验

    1. **文件系统的概念**:文件系统是操作系统用于明确存储设备(常见的是硬盘,也可能是闪存)或分区上的文件的方法和数据结构;即,在存储设备上组织文件的方法。 2. **文件系统的设计目的**: - 提供一种逻辑...

    020文件的教程

    由于没有具体020文件的详细信息,以上内容都是基于一般性假设的概括。实际情况下,需要更多详细资料才能提供更具体的指导。如果你能提供更多关于020文件的背景信息,我可以提供更精确的知识点解析。

    第三周-matlab文件操作-matlab程序设计1-(1)完整.pptx

    MATLAB文件操作和程序设计 MATLAB是一种高性能的技术计算语言和开发环境,广泛应用于数字信号处理、图像处理、控制系统、通信系统、电路分析等领域。下面是MATLAB文件操作和程序设计的知识点总结。 EDA技巧简介 ...

    文件管理控制程序.pdf

    质量手册是质量管理体系的纲领性文件,它概括了本工厂质量管理体系的构成及要素。程序文件是直接支撑质量手册的主要体系文件,是对各部门运作过程及质量体系要求的具体说明。作业指导书是从程序文件中引申出来的,...

    施工合同权利义务概括转让协议.pdf

    根据提供的文件信息,文件名为“施工合同权利义务概括转让协议.pdf”,说明该文档是一份关于施工合同中的权利与义务进行概括性转让的正式协议文本。标题表明协议内容涉及将特定施工合同下的权利和义务,从原合同一方...

    javascript实现将文件保存到本地方法汇总

    而标签"javascript 文件保存到本地"则是对文章主题的一个简洁概括,说明这是一篇专注于在客户端使用JavaScript语言保存文件到本地硬盘的方法的分享文章。 接下来,详细解析给定的示例代码: - 第一个函数saveFile...

Global site tag (gtag.js) - Google Analytics