复制具有不同大小的缓冲区的文件以进行读取和写入

标签 c file buffer

我一直在做一些工作面试的练习题,我遇到了一个我无法集中注意力如何解决它的函数。这个想法是创建一个函数,它获取两个文件的名称、允许从 file1 读取的缓冲区大小和允许写入 file2 的缓冲区大小。如果缓冲区大小相同,我知道如何解决这个问题,但是当大小不同时,我在计算如何在缓冲区之间移动数据时遇到问题。部分限制是我们必须在将写入缓冲区写入文件之前始终填充写入缓冲区。如果 file1 不是 file2 的倍数,我们用零填充最后一个缓冲区传输。

// input: name of two files made for copy, and their limited buffer sizes
// output: number of bytes copied
int fileCopy(char* file1,char* file2, int bufferSize1, int bufferSize2){
int bytesTransfered=0;
int bytesMoved=o;
char* buffer1, *buffer2;
FILE *fp1, *fp2;

fp1 = fopen(file1, "r");
if (fp1 == NULL) { 
    printf ("Not able to open this file"); 
    return -1;
}

fp2 = fopen(file2, "w");
if (fp2 == NULL) {
    printf ("Not able to open this file"); 
    fclose(fp1); 
    return -1;
}

buffer1 = (char*) malloc (sizeof(char)*bufferSize1);
if (buffer1 == NULL) {
    printf ("Memory error");
    return -1;
}

buffer2 = (char*) malloc (sizeof(char)*bufferSize2);
if (buffer2 == NULL) {
    printf ("Memory error"); 
    return -1;
}

bytesMoved=fread(buffer1, sizeof(buffer1),1,fp1);

//TODO: Fill buffer2 with maximum amount, either when buffer1 <= buffer2 or buffer1 > buffer2
//How do I iterate trough file1 and ensuring to always fill buffer 2 before writing?

bytesTransfered+=fwrite(buffer2, sizeof(buffer2),1,fp2);

fclose(fp1);
fclose(fp2);

return bytesTransfered;
}

我应该如何在 fwrite 之前编写用于缓冲区传输的 while 循环?

最佳答案

I am having problems figuring how to move data between the buffers when the sizes are of different

制定计划。对于“求职面试的一些练习题”,良好的计划和证明其合理性的能力很重要。编码虽然重要,但却是次要的。

given valid: 2 FILE *, 2 buffers and their sizes
while  write active && read active
  while write buffer not full && reading active
    if read buffer empty
      read
      update read active
    append min(read buffer length, write buffer available space) of read to write buffer
  if write buffer not empty
    pad write buffer
    write 
    update write active
return file status 

现在编码。更强大的解决方案将使用structFILE*、缓冲区、大小、偏移、长度、事件变量进行分组。

// Return true on problem
static bool rw(FILE *in_s, void *in_buf, size_t in_sz, FILE *out_s,
    void *out_buf, size_t out_sz) {
  size_t in_offset = 0;
  size_t in_length = 0;
  bool in_active = true;
  size_t out_length = 0;
  bool out_active = true;

  while (in_active && out_active) {
    // While room for more data
    while (out_length < out_sz && in_active) {
      if (in_length == 0) {
        in_offset = 0;
        in_length = fread(in_buf, in_sz, 1, in_s);
        in_active = in_length > 0;
      }
      // Append a portion of `in` to `out`
      size_t chunk = min(in_length, out_sz - out_length);
      memcpy((char*) out_buf + out_length, (char*) in_buf + in_offset, chunk);
      out_length += chunk;
      in_length -= chunk;
      in_offset += chunk;
    }

    if (out_length > 0) {
      // Padding only occurs, maybe, on last write
      memset((char*) out_buf + out_length, 0, out_sz - out_length);
      out_active = fwrite(out_buf, out_sz, 1, out_s) == out_sz;
      out_length = 0;
    }
  }
  return ferror(in_s) || ferror(out_s);
}
<小时/>

其他说明;

  1. 不需要转换 malloc() 结果。 @Gerhardh

     // buffer1 = (char*) malloc (sizeof(char)*bufferSize1);
     buffer1 = malloc (sizeof *buffer1 * bufferSize1);
    
  2. 使用 stderr 获取错误消息。 @Jonathan Leffler

  3. 以二进制方式打开文件。

  4. size_t 对于数组/缓冲区大小而言比 int 更稳健。

  5. sizeof buffer1sizeof (buffer1) 视为 sizeof object 不需要括号

关于复制具有不同大小的缓冲区的文件以进行读取和写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45475326/

相关文章:

c - 这个混淆的 C 示例有什么作用?

c++ - 数字中设置的位数

c - 如何判断应用程序是否已经在运行? C 可移植 Linux/Win

c - C语言读取任意长度的文件

c# - Http 上传,保存修改/写入日期?

objective-c - 将自定义元数据应用于文件

C# 套接字接收 : Taking in data until buffer is full dilemma

c - C语言中的按位运算

casting - 为什么ByteData.view(buffer)抛出NoSuchMethodError:类 'String'没有实例方法 'asByteData'

c - 如何连接两个 Lua lua L_Buffer 对象?