linux c学习之文件操作(一)

    最近在看linux C,前五章觉得跟学校里讲的没什么区别,但是一进入第六章,感觉自己什么都不知道,没办法周四自己要实现ls的命令,只好自己硬着头皮看。坚持了三天之后渐渐觉得自己入了门,对文件的操作逐渐有了感觉,也找到了感觉适合自己学习方式。现在先来分享一下自己的学习方法。 刚开始翻到文件操作这一章时候,自己被吓了一跳,什么#include<sys/stat.h>,什么#include<sys/types.h>  这些头文件  基本就没几个见过的。我想这下完了,周四还不知道能不能顺利完成任务....
之后自己就按照书上的,一个一个程序的敲,皇天不负有心人啊,基本上敲到百分之80的时候,感觉来了,看着都能看懂了(前提是敲完一个弄懂一个)。我觉得这个方法很好,计算机就要多实践,才能学会更多。



好了,现在回归正题。现在开始介绍文件的操作。


首先先列个大纲:

part one:
  1. 要是想对文件进行相关操作,首先要有文件。这就要用到open();或者creat();函数来创建文件
  2. 文件创建好了,接着就是对文件操作啦。用到的相关函数有 read();write();函数。从函数名上就能看出这两个函数的功能
  3. 这是大家就会发现,read();和wirte();函数不够自由啊,只能从文件的头行进到尾部。这时,就有用来操作一个文件读写的指针的函数——lseek();
具体介绍一下相关函数:
首先是open(),creat()函数。
#include<fcntl.h>
intopen(const char * pathname,int flags);
intopen(const char * pathname,int flags,mode_tmode);

对于open()函数,头文件跟函数原型已经列出来。现在介绍一下函数的参数分别是怎么用的。pathname就是要打开的文件的路径和文件名。flags表示文件的打开方式。打开方式有:
O_RDONLY 只读模式
O_WRONLY 只写模式
O_RDWR 读写模式 (这三个是必须要选一个,而且仅能选其中一个)

O_APPEND 每次写操作都写入文件的末尾(类似c语言文件的写入时候的追加模式)
O_CREAT 如果指定文件不存在,则创建这个文件
O_EXCL 如果要创建的文件已存在,则返回-1,并且修改errno的值(errno是记录系统的最后一次错误代码。代码是一个int型 的值)
O_TRUNC 如果文件存在,并且以只写/读写方式打开,则清空文件全部内容(即将其长度截短为0)
O_NOCTTY 如果路径名指向终端设备,不要把这个设备用作控制终端。
O_NONBLOCK 如果路径名指向FIFO/块文件/字符文件,则把文件的打开和后继I/O (这六个可根据需要加上)

注意:
当用到O_CREAT这个参数时,就用到第三个参数。第三个参数意思是创建文件时候,文件的权限位(就是文件存取的权限)。文件的实际存取权限是(mode& ~umask)而来。为了简单明了,我们可以记这些参数

S_IRWXU 所有者具有可读可写可执行的权限
S_IRWXG 所有者所在的group具有可读可写可执行的权限
S_IRWXO 其他用户具有可读可写可执行的权限
就介绍这几个 有兴趣的可以查查
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
C语言:#include<io.h>
int creat(const char * pathname , mode_t mode);


看到这个creat()函数的原型,接着比较一下open()函数的第二个原型。所以说creat函数用法很接近,但是头文件差异很大。这里就不介绍了。

贴一个使用的列子:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

int main(int argc, char *argv[])
{
	int fd;
	if((fd = open( "example.c" , O_CREAT | O_EXCL , S_IRUSR | S_IWUSR )) == -1 )  {
		perror("open");
		printf("open:%s     with errno:%d\n",strerror(errno),errno);	
	}
	else  {
		printf("creat file success\n");
	}

	close(fd);
	return 0;
}


在c语言中我们见过fread(),fwrite()函数。现在我们看到了没见过的函数,man一下。可以看到
#include <unistd.h>
ssize_t  r表明文件开始处到文件当前位置的字节数。
ead( int fd , void *buf , size_t  count ); ssize_t write ( int fd , const void * buf , size_t count );
size_t 是为了方便系统之间的移植而定义的      ssize_t是signed size_t
对于read函数,这个函数的意思是,从fd所指的文件中,读出count个字节到buf所指的缓存中。同理,wirte函数是把buf缓存区的count个字节数据写入到fd所指的文件中。很好理解就贴一个代码就好了。
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

void my_err( const char * err_string, int line )
{
	fprintf(stderr,"line:%d ",line);
	perror(err_string);
	exit(1);
}

int my_read( int fd )
{
	int len;
	int ret;
	int i;
	char read_buf[64];

	if( lseek( fd , 0 , SEEK_END) == -1 )  {
		my_err("lseek",__LINE__);
	}
	if(( len = lseek(fd , 0 , SEEK_CUR )) == -1 ) {
	      my_err("lseek",__LINE__);
	}
	if((lseek(fd, 0 , SEEK_SET)) == -1 )  {
		my_err("lseek",__LINE__);
	}

	printf("len:%d\n",len);
	if((ret = read(fd , read_buf , len)) < 0 )  {
		my_err("read",__LINE__);
	}

	for( i = 0 ; i < len ; i++ )  {
		printf("%c",read_buf[i]);
	}
	printf("\n");

	return ret;
}


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

	int fd;
	char write_buf[32] = "hello world!";
	//if((fd = open( "example.c" , O_CREAT | O_RDWR | O_TRUNC , S_IRWXU )) == -1 )  {
	if((fd = creat("example.c", S_IRWXU)) == -1) {
		my_err("open",__LINE__);
	}
	else {
		printf("creat file success\n");
	}

	if(write(fd , write_buf , strlen(write_buf) != strlen(write_buf)))  {
		my_err("write",__LINE__);
	}

	my_read(fd);

	printf("/*---------------------------------*/\n");
	if(lseek(fd , 10 , SEEK_END ) == -1 )  {
		my_err("lseek",__LINE__);
	}
	if(write( fd , write_buf , strlen(write_buf)) != strlen(write_buf) )  {
		my_err("write",__LINE__);
	}
	my_read(fd);
	close(fd);
	return 0;
}


接下来介绍lseek函数
#include <sys/types.h>     #include <unistd.h>
off_t  lseek( int fd , off_t  offset , int whence );
lseek这个函数,第一个参数是指向某一文件的参数。第二个参数是表明文件开始处到文件当前位置的字节数。除非打开方式为O_APPEND。第三个参数是从哪开始计算偏移量。有三个参数
SEEK_SET    从文件开始计算偏移量。
SEEK_CUR  从文件当前位置开始计算偏移量。(文件指针的值是此位置的偏移量加上offset的值)
SEEK_END  从文件末尾处开始计算偏移量。
通过lseek这个函数就可以把文件指针移动到想移动到的位置(天马行空就算了)。lseek( fd ,0 , 三个参数 );
具体用法贴个例子:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

void my_err( const char * err_string, int line )
{
	fprintf(stderr,"line:%d ",line);
	perror(err_string);
	exit(1);
}

int my_read( int fd )
{
	int len;
	int ret;
	int i;
	char read_buf[64];

	if( lseek( fd , 0 , SEEK_END) == -1 )  {
		my_err("lseek",__LINE__);
	}
	if(( len = lseek(fd , 0 , SEEK_CUR )) == -1 ) {
	      my_err("lseek",__LINE__);
	}
	if((lseek(fd, 0 , SEEK_SET)) == -1 )  {
		my_err("lseek",__LINE__);
	}

	printf("len:%d\n",len);
	if((ret = read(fd , read_buf , len)) < 0 )  {
		my_err("read",__LINE__);
	}

	for( i = 0 ; i < len ; i++ )  {
		printf("%c",read_buf[i]);
	}
	printf("\n");

	return ret;
}


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

	int fd;
	char write_buf[32] = "hello world!";
	//if((fd = open( "example.c" , O_CREAT | O_RDWR | O_TRUNC , S_IRWXU )) == -1 )  {
	if((fd = creat("example.c", S_IRWXU)) == -1) {
		my_err("open",__LINE__);
	}
	else {
		printf("creat file success\n");
	}

	if(write(fd , write_buf , strlen(write_buf) != strlen(write_buf)))  {
		my_err("write",__LINE__);
	}

	my_read(fd);

	printf("/*---------------------------------*/\n");
	if(lseek(fd , 10 , SEEK_END ) == -1 )  {
		my_err("lseek",__LINE__);
	}
	if(write( fd , write_buf , strlen(write_buf)) != strlen(write_buf) )  {
		my_err("write",__LINE__);
	}
	my_read(fd);
	close(fd);
	return 0;
}




这个文章颜色较花,我觉得比较像vim的配置,给人很好看的感觉。我感觉我介绍比较详细,我看书时候有些还看不懂,百度了好多。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值