Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1619804
  • 博文数量: 441
  • 博客积分: 20087
  • 博客等级: 上将
  • 技术积分: 3562
  • 用 户 组: 普通用户
  • 注册时间: 2006-06-19 15:35
文章分类

全部博文(441)

文章存档

2014年(1)

2012年(1)

2011年(8)

2010年(16)

2009年(15)

2008年(152)

2007年(178)

2006年(70)

分类: C/C++

2007-08-29 17:33:55

拷贝文件实际上就是将一个文件的内容读出来再写入另一个新文件,在linux C中要实现这操作,主要用到下面3个文件操作函数:
(1)open

       #include
       #include
       #include

       int open(const char* pathname, int flags, mode_t mode);

       pathname 为文件的路径名称, flags为文件的打开方式, mode 为访问权限
      flags常见取值:
          O_RDONLY:以只读的方式打开文件.
          O_WRONLY:以只写的方式打开文件.
          O_RDWR:以读写的方式打开文件.
          O_APPEND:以追加的方式打开文件.
          O_CREAT:创建一个文件.
          O_EXEC:如果使用了O_CREAT 而且文件已经存在,就会发生一个错误.
          O_NOBLOCK:以非阻塞的方式打开一个文件.
          O_TRUNC:如果文件已经存在,则删除文件的内容.
         前面三个标志只能使用任意的一个.
    mode常见取值:
        S_IRUSR 用户可以读 S_IWUSR 用户可以写
        S_IXUSR 用户可以执行 S_IRWXU 用户可以读写执行

        S_IRGRP 组可以读 S_IWGRP 组可以写
        S_IXGRP 组可以执行 S_IRWXG 组可以读写执行

        S_IROTH 其他人可以读 S_IWOTH 其他人可以写
        S_IXOTH 其他人可以执行 S_IRWXO 其他人可以读写执行

        S_ISUID 设置用户执行ID S_ISGID 设置组的执行ID

       我们也可以用数字来代表各个位的标志.Linux 总共用5 个数字来表示文件的各种权限.
       00000.第一位表示设置用户ID.第二位表示设置组ID,第三位表示用户自己的权限位,第
      四位表示组的权限,最后一位表示其他人的权限.
     每个数字可以取1(执行权限),2(写权限),4(读权限),0(什么也没有)或者是这几个值的和

(2) read , write

     #include
    
      ssize_t read(int fd, void *buffer,size_t count);

      ssize_t write(int fd, const void *buffer,size_t count);

     fd 是我们要进行读写操作的文件描述符,buffer 是我们要写入文件内容或读出文件内容的
    内存地址.count 是我们要读写的字节数.
    对于普通的文件read 从指定的文件(fd)中读取count 字节到buffer 缓冲区中(记住我们必
   须提供一个足够大的缓冲区),同时返回count.
   如果read 读到了文件的结尾或者被一个信号所中断,返回值会小于count.如果是由信号中
    断引起返回,而且没有返回数据,read 会返回-1,且设置errno 为EINTR.当程序读到了文件
    结尾的时候,read 会返回0.
    write 从buffer 中写count 字节到文件fd 中,成功时返回实际所写的字节数

关于这三个函数更详细的说明可参见man。

下面是用这三个函数实现的一个拷贝文件的例子:

/* cpfile.c */

#include
#include
#include
#include
#include
#include
#include
#include

#define    BUF_SIZE    1024

int main(int argc, char **argv)
{
    int from_fd, to_fd;
    int bytes_read, bytes_write;
    char buffer[BUF_SIZE];
    char *ptr;

    if ( argc != 3 )
    {
        fprintf(stderr, "Usage: %s fromfile tofile\n\a", argv[0]);
        exit(1);
    }
   
    /* open source file */
    if ( ( from_fd = open(argv[1], O_RDONLY) ) == -1 )
    {
        fprintf(stderr, "Open %s error : %s\n", argv[1], strerror(errno));
        exit(1);
    }
   
    /* create target file */
    if ( (to_fd = open(argv[2], O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR) ) == -1 )
    {
        fprintf(stderr, "Create %s error : %s\n\a", argv[2], strerror(errno));
        exit(1);
    }

    /* start to copy file */
    while ( bytes_read = read(from_fd, buffer, BUF_SIZE) ) /* read BUF_SIZE bytes to buffer */
    {
        /* error occurs when read */
        if ( ( bytes_read == -1) && ( errno != EINTR) ) break;
        else if ( bytes_read > 0 ) /* read successfully */
        {
            ptr = buffer;   /* point to buffer */
            while ( bytes_write = write(to_fd, ptr, bytes_read) ) /* write bytes_read bytes to target file */
            {
                if ( (bytes_write == -1) && (errno != EINTR) ) break;   /* error occurs */
                else if ( bytes_write == bytes_read ) break;   /* write all bytes that read from buffer */
                else if ( bytes_write > 0 )  /* continue to write left bytes in the buffer */
                {
                    ptr += bytes_write;   /* pointer to next block which will be write */
                    bytes_read -= bytes_write;  /* calculate bytes needs to write */
                }
            }       
           
            if ( bytes_write == -1 ) break;   /* error occurs when write file */
        }
    }   
    close(from_fd);   /* close file description */
    close(to_fd);
    return 0;
}


该程序分为两个循环,在外循环,不断的从源文件中读取BUF_SIZE即1024个字节到缓冲区buffer,
内循环中,将buffer中的文件内容写入目标文件,如果一次没有写完,则继续写,直到都写完,
当缓冲区中的内容都写到了目标文件中去,则退出内循环,回到外循环,继续从源文件读取接下来的1024个字节到缓冲区,然后继续内循环作写操作,直到所有源文件的内容都写到了目标文件,则退出外循环,当然,中间任何一个环节出现错误,就立即结束循环,退出来,最后关闭源文件和目标文件描述符。
阅读(2223) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~