linux程序设计—文件操作

一、底层文件访问方式

(一)文件描述符

0:标准输入

1:标准输出

2:标准错误

(二)write系统调用

1、系统原型

#include<unistd.h>

size_t write(int fildes,const void *buf,size_t nbytes);

2、示例程序
#include <unistd.h>
#include <stdio.h>

int main()
{
	if((write(1,"Here is some data\n",18))!=18)
		write(2,"A write error has occurred on file descriptor 1\n",46);
	
	exit(0);
}
3、输出

Here is some data

(三)read系统调用

1、系统原型

#include<unistd.h>

size_t read(int fildes,void *buf,size_t nbytes);

2、示例程序

#include <unistd.h>
#include <stdlib.h>
int main(){
	char buffer[128];
	int nread;

	nread = read(0,buffer,128);
	if(nread==-1)
		write(2,"A read error has occurred\n",26);

	if((write(1,buffer,nread))!=nread)
		write(2,"A write errot has occurred\n",27);

	exit(0);
}

3、输出

$echo hello world | ./3.4.2_simple_read
hello world

(四)open系统调用

1、系统原型

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

int open(const char *path,int oflags);
int open(conat char *path,int oflags,mode_t mode);

2、oflags的类型

O_RDONLY    以只读方式打开
O_WRONLY    以只写方式打开
O_RDWR	    以读写方式打开
O_APPEND    将写入的数据追加在文件的末尾
O_TRUNC     将文件长度设置为0,丢弃已有的内容
O_CREAT     如果需要,按照mode给出的参数创建文件
O_EXCL      与O_CREAT一起使用,确保调用者创建出文件
前三个必须要选择一个,且仅一个,后面的类型与选中的通过“|”运算符配合使用

3、mode访问权限初始值

S_IRUSR     读权限,文件属主
S_IWUSR     写权限,文件属主
S_IXUSR     执行权限,文件属主
S_IRGRP     读权限,文件所属组
S_IWGRP     写权限,文件所属组
S_IXGRP     执行权限,文件所属组
S_IROTH     读权限,其他用户
S_IWOTH     写权限,其他用户
S_IXOTH     执行权限,其他用户

(五)close系统调用

1、系统原型

#include <unistd.h>

int close(int fildes);

(六)示例程序

1、文件复制程序

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

int main()
{
	char block[100];
	int in,out;
	int nread;
	in = open("file.in",O_RDONLY);
	out = open("file.out",O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR);
	while((nread= read(in,block,sizeof(block)))>0)
		write(out,block,nread);

	exit(0);
}

2、输出

TIMEFOMAT="" time ./copy_block
0.00user 0.00system 0:00.00elapsed 66%CPU

二、标准I/O库

(一)fopen函数

1、函数原型

#include <stdio.h>

FILE *fopen(const char *filename,const char *mode);

2、mode取值

"r"或"rb"            以只读方式打开
"w"或"wb"            以写方式打开,并使文件长度为0
"a"或"ab"            以写方式打开,新内容追加在文件尾部
"r+"或"rb+"或"r+b"   以更新方式打开(读和写)
"w+"或"wb+"或"w+b"   以更新方式打开,并使文件长度为0
"a+"或"ab+"或"a+b"   以更新方式打开,新内容追加在文件尾

(二)fread,fwrite,fclose,fflush,fseek,fgetc,getc,getchar,fputc,putc,putchar,fgets,gets函数

1、函数原型

#include <stdio.h>
size_t fread(void *ptr,size_t size,size_t nitems,FILE *stream);//nitems给出了要传输的记录的个数

size_t fwrite(void *ptr,size_t size,size_t nitems,FILE *stream);//nitems给出了要传输的记录的个数

int fclose(FILE *stream);//关闭指定的文件流,隐含执行一次fflush

int fflush(FILE *stream);//将文件流里所有未写出的数据都写出,无需在fclose之前调用

int fseek(FILE *stream,long int offset,int whence);//指定下一次读写操作的位置;返回0表示成功,-1表示失败

int fgetc(FILE *stream);
int getc(FILE *stream);
int getchar();

int fputc(FILE *stream);
int putc(FILE *stream);
int putchar();

char *fgets(char *s,int n,FILE *stream);//每次调用最多传输n-1个字符,最后一个字符用于存放‘\0’.
char *gets(char *s);//读取数据并丢弃遇到的换行符

2、示例程序
#include<stdio.h>
#include <stdlib.h>

int main()
{
	int c;
	FILE *in,*out;
	in = fopen("file.in","r");
	out = fopen("file.out","w");
	
	while((c= fgetc(in))!=EOF)
		fputc(c,out);

	exit(0);
}

3、输出

TIMEFOMAT="" time ./copy_stdio
0.00user 0.00system 0:00.00elapsed 75%CPU 

三、文件和目录维护函数

1、各个函数原型

#include <sys/stat.h>
int chmod(const char *path,mode_t mode);//改变文件或是目录的访问权限。mode参数与open系统调用一样


#include<sys/types.h>
#include <unistd.h>
int chown(const char *path,uid_t owenergid_t group);//改变文件的属主

#include <unistd.h>
int unlink(const char *path);
int link(const char *path1,const char *path2);
int symlink(const char *path1,const char *path2);//创建符号链接,符号链接不会增加文件的连接数。

#include <sys/types.h>
#include <sys/stat.h>
int mkdir(const char *path,mode_t mode);

#include <unistd.h>
int rmdir(const char *path);


#include <unistd.h>
int chdir(const char *path);//切换到当前目录

#include <unistd.h>
char *getcwd(char *buf,size_t size);//获取当前目录到buf中

四、扫描目录函数

1、函数原型

#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);//打开一个目录

struct dirent *readdir(DIR *dirp);//返回一个保存着目录流dirp中下一个目录项有关资料的指针

long int telldir(DIR *dirp);//返回目录流的当前位置

void seekdir(DIR *dirp,long int loc);//设置目录流dirp的目录项指针

int closedir(DIR *dirp);
其中,dirent结构中包含目录项内容如下:
ino_t d_nio:文件的inode节点号
char  d_name[]:文件的名字

2、程序示例(一个目录扫描程序)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>

void printdir(char *dir,int depth)//输出当前目录的内容,depth用来控制缩排
{
        DIR *dp;
        struct dirent *entry;
        struct stat statbuf;

        if((dp = opendir(dir))==NULL){//检查指定目录是否存在
                fprintf(stderr,"cannot open directory: %s\n",dir);
                return ;
        }

        chdir(dir);//进入指定目录

        while((entry=readdir(dp))!=NULL){//检查该数据项是否是一个目录
                lstat(entry->d_name,&statbuf);
                if(S_ISDIR(statbuf.st_mode)){
                        if(strcmp(".",entry->d_name)==0
                        ||strcmp("..",entry->d_name)==0)
                               continue;
                        printf("%*s%s/\n",depth,"",entry->d_name);
                        printdir(entry->d_name,depth+4);
                }
                else printf("%*s%s\n",depth,"",entry->d_name);
        }
        chdir("..");//返回上一级目录
        closedir(dp);
}

int main(int argc, char* argv[]){
        char *topdir = ".";
        if(argc>=2)
                topdir = argv[1];

        printf("Directory scan of %s:\n",topdir);
        printdir("/home",0);
        printf("done.\n");
        exit(0);
}

3、输出

./3.8.5_printdir /home | more
Directory scan of /home:
xxxxxxx/
    .mozilla/
        extensions/
            {ec8030f7-c20a-464f-9b0e-13a3a9e97384}/
        plugins/
        firefox/
            7j5tb4bn.default/
                times.json
                .parentlock
.............
	.esd_auth
    .bash_history
    .viminfo
done.






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值