Linux_c编程——copy函数

来源:互联网 发布:linux nginx 全局变量 编辑:程序博客网 时间:2024/06/06 18:13

c编程——copy函数

         这里我所讲的就直接是在linux环境下的C编程了,所用的就是gcc编译器。关于写自己的copy函数,我们用的全部是系统调用,需要用到的系统函数 read 和 write,还有open,以前我们用的fopen是open的封装,而且fopen是标准库的函数。

所以我就先讲一下这三个个系统函数。

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
返回值:成功返回新分配的文件描述符,出错返回-1并设置errno。

参数:

char *pathname 是文件的路径,这个路径可以是绝对路径,也可以是相对路径。

int flag:

必选项:以下三个常数中必须指定一个,且仅允许指定一个。
O_RDONLY 只读打开
O_WRONLY 只写打开
O_RDWR 可读可写打开
以下可选项可以同时指定0个或多个,和必选项按位或起来作为flags参数。可选项有很多,这里只
介绍一部分,其它选项可参考open(2)的Man Page:
O_APPEND 表示追加。如果文件已有内容,这次打开文件所写的数据附加到文件的末尾而不覆
盖原来的内容。
O_CREAT 若此文件不存在则创建它。使用此选项时需要提供第三个参数mode,表示该文件的访
问权限。
O_EXCL 如果同时指定了O_CREAT,并且文件已存在,则出错返回。
O_TRUNC 如果文件已存在,并且以只写或可读可写方式打开,则将其长度截断
(Truncate)为0字节。
O_NONBLOCK 对于设备文件,以O_NONBLOCK方式打开可以做非阻塞I/O(Nonblock I/O)。

注意open函数与C标准I/O库的fopen函数有些细微的区别:
以可写的方式fopen一个文件时,如果文件不存在会自动创建,而open一个文件时必须明确指
定O_CREAT才会创建文件,否则文件不存在就出错返回。
以w或w+方式fopen一个文件时,如果文件已存在就截断为0字节,而open一个文件时必须明确
指定O_TRUNC才会截断文件,否则直接在原来的数据上改写。
第三个参数mode指定文件权限,可以用八进制数表示,比如0644表示-rw-r--r--,也可以
用S_IRUSR、S_IWUSR等宏定义按位或起来表示。

 

然后是read函数:

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
返回值:成功返回读取的字节数,出错返回-1并设置errno,如果在调read之前已到达文件
末尾,则这次read返回0。

ssize:成功读到的字节数。

int fd:fd为文件描述符。

void *buf:把从文件读出的东西存放在buf中。

size_t count:以此read调用所读的字节数。

 

write:

#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
返回值:成功返回写入的字节数,出错返回-1并设置errno

和read一样。

 

我主要讲一下拷贝部分的代码,其他代码读者自己可以看懂。

 

这里我们考虑的一个突发情况是:

当你读取了10个字节在缓冲中,但是在写入的时候却只写了3个字节,所以我们需要判断一下写入的字节是否和读出的字节一样多。

所以多加了一个while(read_size){}循环。

现在我们讨论突发情况,当write_size只有3时,我们还要继续写7个字节进去,

所以read_size=read_size-write_size。

因为我们已经写进去了3个字节,所以buf地址要往后移动3字节的长度,而我们的buf是规定死了的,所以用个变量tmp=buf,

然后tmp=tmp+write_size。

在里面这个while(read_size){}循环里,read_size不为0,所以继续写7个字节到文件中,这时read_size为0了,退出循环。再到大循环中。

 

这样就保证了 所有读到的数据都能写入到目标文件中去了。

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

#define MSG_WRONG "something wrong\n"
void copy(int fread,int fwrite);

int main(int argc,char *argv[])
{
 int fread,fwrite;
 
 fread=open(argv[1],O_RDONLY);
 fwrite=open(argv[2],O_WRONLY|O_CREAT,0644);
 if(fwrite<0|fread<0|argc!=3)
 {
  printf(MSG_WRONG);
  exit(1);
 }
 if(argc!=3)
 {
  printf(MSG_WRONG);
  exit(1) ;
 }
 else
 {
  copy(fread,fwrite);
 }
 close(fread);
 close(fwrite);
 return 0;
}
void copy(int fread,int fwrite)
{
 int read_size,write_size;
 char buf[10];
 char *tmp;
 read_size=-1;
 while((read_size=read(fread,buf,10))>0)
 {
  tmp=buf;
  while(read_size)
  {
   write_size=write(fwrite,tmp,read_size);
   read_size=read_size-write_size;
   tmp+=write_size;
  }

 }

}

 

0 0
原创粉丝点击