linux文件操作相关函数

1、chmod/fchmod:文件的访问权限控制

函数原型:

#include <sys/stat.h>
int chmod(const char *path, mode_t mode);	//path:文件名;mode:文件权限
int fchmod(int fd, mode_t mode);	//fd:文件描述符
两者的区别:chmod 以文件名作为第一个参数,fchmod以文件描述符作为第一个参数。权限更改成功返回0,失败返回-1,错误代码存于系统预定义变量errno中。(利用chmod函数可以实现自己的简化版chmod命令)

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>

int main(int argc,char ** argv)
{
    int    mode; //权限
    int    mode_u;  //所有者的权限
    int    mode_g;  //所属组的权限
    int    mode_o;  //其他用户的权限
     char    *path;
    
    /*检查参数个数的合法性*/
    if(argc < 3) {
        printf("%s <mode num> <target file> ",argv[0]);
        exit(0);
    }
    
    /*获取命令行参数*/
    mode = atoi(argv[1]);
    if (mode > 777 || mode < 0){
            printf("mode num error! ");
        exit(0);
    }
    mode_u = mode / 100;
    mode_g = (mode - (mode_u*100)) / 10;
    mode_o = mode - (mode_u*100) - (mode_g*10);  //八进制转换
    path = argv[2];

    if ( chmod(path,mode) == -1){
        perror("chmod error");
        exit(1);
    } 
        return 0;
}


2、文件的输入输出:creat、open、close、read、write和lseek等。
它们这些系统调用都是使用文件描述符来标识文件,(文件描述符是UNIX/Linux特有的),对内核而言,所有打开的文件都由文件描述符标识。文件描述符是一个非负整数。在读写一个文件前,需要现调用open或creat函数打开文件,成功执行这两个函数都将返回一个文件描述符。在对文件执行读写操作时,将其作为参数传递给read或write。文件描述符的取值范围在0~NR—OPEN之间,Linux中NR—OPEN为255,也就是说每个程序最多只能打开256个文件。
(1)open和creat函数:open和creat系统调用用来打开或创建一个文件
函数原型为:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);	//pathname是要打开或创建的含路径的文件名,第二个参数flags表示打开文件的方式。
int open(const char *pathname, int flags, mode_t mode);	//当且仅当第二个参数使用了O—CREAT时,需要使用第三个参数mode,以说明新文件的存取权限。(新文件的实际存取权限是mode与umask按照(mode& ~umask)运算以后的结果)
int creat(const char *pathname, mode_t mode);	//第一个参数是要打开或创建的文件名,如果pathname指向的文件不存在,则创建一个新文件;如果指向的文件存在,则原文件被新文件覆盖。
打开文件的方式:O—RDONLY、O—WRONLY、O—RDWR  分别以只读、只写或可读可写的方式打开。这三种打开方式是互斥的,不能同时以两种或三种方式打开文件,但可以分别与下列标志进行或运算:

O—CREAT:若文件不存在则自动建立该文件,只有在此时需要用到第三个参数mode,以说明新文件的存取权限。
O—EXCL: 如果O—CREAT也被设置,此指令会去检查文件是否存在。文件若不存在则创建,若存在则导致打开文件出错。
O—TRUNC:若文件存在并且以可写的方式打开时,此标志会将文件长度清0,即源文件中保存的数据将丢失,但文件属性不变。
O—APPEND:所写入的数据会以追加的方式加入到文件后面。
O—SYNC:以同步的方式打开文件,任何对文件的修改都会阻塞直到物理磁盘上的数据同步以后才返回。
O—NOFOLLOW:如果参数pathname所指的文件为一符号链接,则会令打开文件失败。
O—DIRECTORY:如果参数pathname所指的文件并非一目录,则会令打开文件失败。
O—NONBLOCK或O—NDELAY:以非阻塞的方式打开文件,对于open及随后的对该文件的操作,都会立即返回。


(2)close函数:close系统调用用来关闭一个已经打开的文件。
函数原型为:

#include <unistd.h>
int close(int fd);
代码例子:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>

int main()
{
    int fd;

    if((fd = open("example.c",O_CREAT|O_EXCL,S_IRUSR| S_IWUSR)) == -1)
    {
	//从错误代码中获取相应的错误描述
	printf("open:%s with errno:%d ",strerror(errno),errno);
        exit(1);     
    }else
    {
        printf("Create file success ");
    }
    close(fd);
    return 0;
}


3、文件的读写:read和write函数
(1)read函数:read系统调用用来从打开的文件中读取数据。函数原型:

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);   //从文件描述符fd所指向的文件中读取count个字节的数据到buf所指向的缓存中。
如果count为0,则read()不会读取数据,只返回0。返回值表示实际读取到的字节数。如果返回0,表示已达到文件尾或者是无可读取数据。文件读写指针会随读取到的字节移动。当错误发生时则返回-1,错误代码存入errno中。
(2)write函数:write系统调用用来将数据写入已打开的文件中。函数原型:

#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);

4、文件读写指针的移动:lseek系统调用用来移动文件读写指针的位置。

函数原型:

#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);	//offset为根据参数whence来移动读写位置的位移数。
whence有3种取值:
SEEK—SET从文件开始处计算偏移量,文件指针到文件开始处的距离为offset。
SEEK—CUR从文件指针的当前位置开始计算偏移量,文件指针值等于当前指针值加上offset的值,offset允许取负数。
SEEK—END 从文件结尾处开始计算偏移量,文件指针值等于当前指针值加上offset的值,offset允许取负数。
对应的用法如下:
lseek(int fildes,0,SEEK_SET);  将文件读写指针移动到文件开头
lseek(int fildes,0,SEEK_END);  将文件读写指针移动到文件结尾
lseek(int fildes,0,SEEK_CUR); 获取文件读写指针当前的位置(相对于文件头的偏离)

代码例子:

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

int main()
{
	char* path = "test.txt";
	struct stat buf;
	if (stat(path, &buf)<0)
	{
		printf("can't get file infomation.");
		return -1;
	}
	//1:获取文件大小
	int size= buf.st_size;
	printf("file size:%d.",size);

	//2:读取文件
	int fbfd =open(path, O_RDONLY);
	if (!fbfd)
	{
		printf("Error: cannot open file.\n");
     		return -1;
	} 
	//设置偏移量为0,即文件的开头
	char buffer[256];
	lseek(fbfd,0,SEEK_SET);
	//while(1)
	{
            //每次读取256个字符 
	    int nread = read(fbfd,buffer,256);
            int n = 0;	
	    if(nread > 0)
            {  		
        	for(n=0;n<nread;n++)
                {
                    printf("%c",buffer[n]);
                }
                printf("\n");
            }
            else
            {
                printf("Read error, nread=%d\n",nread);
                //break;
            }
        }
        printf("Read end\n");
	return 0;
}

5、输入/输出的重定向:dup、dup2函数
dup与dup2函数常用于实现输入、输出的重定向。(将文件的描述符赋值给其他变量,如将文件复制到标准输入输出中)
函数原型:
#include <unistd.h>
int dup(int oldfd);
int dup2(int oldfd, int newfd);
dup函数用于复制指定的文件描述符。函数返回的新描述符是当前进程最小的未使用的描述符。
dup2函数也是用户复制指定的文件描述符,只是参数与dup函数存在不同。如果新的文件描述符已经打开(newfd),将会先关闭新的文件描述符。

在linux中还定义了如下的宏,方便程序员对标准输入、输出和错误输出进行控制。
STDIN—FILENO:标准输入,其值为0。
STDOUT—FILENO:标准输出,其值为1。
STDERR—FILENO:标准错误输出,其值为2。
错误信息:
EBADF:oldfd不是打开的文件描述符,或newfd超出了文件描述符允许的范围。
EBUSY:在使用open函数和dup函数时发生了冲突,dup2函数返回该错误。
EMFILE:进程打开文件达到上限。

6、文件控制:fcntl函数
fcntl系统调用可以用来对已打开的文件描述符进行各种控制操作以改变已打开文件的各种属性,其函数原型如下:
#include <unistd.h>
#include <fcntl.h>

int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值