【问题标题】:Cannot copy an entire file to another one using write system call无法使用 write 系统调用将整个文件复制到另一个文件
【发布时间】:2013-09-28 05:54:56
【问题描述】:

我必须将 file1 的内容复制到一个缓冲区(大小为 23 字节),然后,我必须将数据从缓冲区复制到 file2。

我无法确保将 file1 完全复制到缓冲区中。当缓冲区复制到 file2 时,file2 只包含 file1 的部分内容,并且输出说只有 4 个字节的数据被复制到了 file2。

我试图弄清楚我做错了什么,但到目前为止我还没有运气。您的帮助将不胜感激。

我正在使用安装了 Ubuntu 的 Oracle VM VirtualBox。

我还使用 make (MakeFile) 在命令提示符下一次更新所有文件。

我的代码在 C/POSIX 下面。

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

#define  My_Full_Name "AAA!"

int PrintSentence()
{

  size_t buffersize = (size_t) (4 * 5.75);  //or (4 bytes * 5.75) = 23 bytes
  char buffer[buffersize];
  char source_file[200];
  char destination_file[200];

  ssize_t bytes_read;

  int fdSource, fdDestination;

  mode_t mode = S_IRUSR | S_IWUSR;

  printf("Welcome to File Copy by %s\n", My_Full_Name);

  printf("Enter the name of the source file: ");

  scanf("%s", source_file);

  printf("Enter the name of the destination file: ");

  scanf("%s", destination_file);

  fdSource = open(source_file, O_RDONLY);

  if (fdSource < 0)
  {
    perror("Open failed!!");
    return 1;
  }

  else
  {

    bytes_read = read(fdSource, buffer, sizeof(buffer));

    fdDestination = open(destination_file, O_CREAT | O_WRONLY | mode);

    if (fdDestination < 0)
    {
      perror("Oups!! cannot create file again!!");

      return 1;
    }
    else
    {
      write(fdDestination, buffer, sizeof(buffer));
      printf("current content of buffer: %s\n", buffer); //just to check
      printf("current value of buffer size = %zd  \n", buffersize); //just to check
      printf("File copy was successful, with %d byte copied\n", fdDestination); //the output says only 4 bytes are copied

    }

  }

  return;

}

【问题讨论】:

    标签: c buffer posix system-calls file-copying


    【解决方案1】:

    这里:

    printf("File copy was successful, with %d byte copied\n", fdDestination );
    

    fdDestination 是一个文件描述符,它不是写入的字节数。 012 是您的三个标准流,3 将是您首先打开的输入文件,所以4 将是您的输出文件,这就是为什么它总是输出 4

    您想保存来自write() 的返回值,并改用它的值(当然,在检查该返回值是否有错误之后,您也应该为read() 执行此操作)。

    编辑:稍微修改您的代码:

    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <stdlib.h>
    
    #define  My_Full_Name "AAA!"
    
    int main(void) {
        size_t buffersize = (size_t) (4 * 5.75);
        char buffer[buffersize];
        char source_file[200];
        char destination_file[200];
    
        ssize_t bytes_read, bytes_written;
        int fdSource, fdDestination;
    
        mode_t mode = S_IRUSR | S_IWUSR;
    
        printf("Welcome to File Copy by %s\n", My_Full_Name);
        printf("Enter the name of the source file: ");
        scanf("%s", source_file);
    
        printf("Enter the name of the destination file: ");
        scanf("%s", destination_file);
    
        fdSource = open(source_file, O_RDONLY);
    
        if (fdSource < 0) {
            perror("Open failed!!");
            return 1;
        } else {
            bytes_read = read(fdSource, buffer, sizeof(buffer));
            fdDestination = open(destination_file, O_CREAT | O_WRONLY | mode);
    
            if (fdDestination < 0) {
                perror("Oups!! cannot create file again!!");
                return 1;
            } else {
                bytes_written = write(fdDestination, buffer, sizeof(buffer));
                printf("current content of buffer: %s\n", buffer);
                printf("current value of buffer size = %zd  \n", buffersize);
                printf("File copy was successful, with %d byte copied\n",
                        bytes_written);
            }
        }
    
        return 0;
    }
    

    给我这个:

    paul@local:~/src/c/fpc$ cat infile
    12345678901234567890123
    paul@local:~/src/c/fpc$ ./fpc
    Welcome to File Copy by AAA!
    Enter the name of the source file: infile
    Enter the name of the destination file: outfile
    current content of buffer: 12345678901234567890123
    current value of buffer size = 23
    File copy was successful, with 23 byte copied
    paul@local:~/src/c/fpc$ cat outfile; echo ""
    12345678901234567890123
    paul@local:~/src/c/fpc$
    

    【讨论】:

    • 谢谢!它按照您的建议修复了正确复制的字节数。但我仍然没有将 file1 的全部内容放入缓冲区,并放入 file2。
    • 您是否正在检查来自read()write() 的返回以检查它们实际读取和写入的字节数?而且您的输入文件正好是 23 个字节长,对吧?
    • 是的,我确实检查了 read() 和 write() 的返回,并且都返回 23 个字节。我意识到 file1 和 file2 比缓冲区大。因此,我将只有文件的一部分(最多 23 个字节)是有道理的。感谢您的帮助!
    • 没问题。如果您想复制其余部分,则似乎需要某种循环。
    • 快速问题:如果文件非常小,比如 1 到 2 个字符,如何确保 read() 和 write() 返回完全相同的值?我很难为非常小的文件获得相同的返回值。
    【解决方案2】:

    当您的缓冲区只有 23 个字节长时,您怎么能期望文件会被完全写入缓冲区?通过调用读取,您仅读取 23 个字节,而保留 file1 的其余内容不变。或者,您的程序应该只将其内容的 23 个字节复制到目标文件,这是您的预期行为吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 2016-03-22
      • 2014-04-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多