简体   繁体   中英

Copy data from file X to file Y program in C

I tried to write basic program in C which copy data from file to another with given source path, destination path and buffer size as input. my problem is the destination file filled with junk or something because its way larger than the source (get bigger depending on buffer size) and can't be open. How do i read and write just the bytes in the source? i'm working in linux, and this is the actually copying part:

char buffer[buffer_size];

int readable=1;
int writeable;
while(readable != 0){
    readable = read(sourcef, buffer, buffer_size);
    if(readable == -1){
        close(sourcef);
        close(destf);
        exit_with_usage("Could not read.");
    }
    writeable = write(destf, buffer, buffer_size);
    if(writeable == -1){
        close(sourcef);
        close(destf);
        exit_with_usage("Could not write.");
    }
}
 writeable = write(destf, buffer, buffer_size); 

must be

writeable = write(destf, buffer, readable);

Currently you do not write the number of characters you read but all the buffer, so the output file is too large

You also manage wrongly the end of the input file

The return value of read is :

  • On success, the number of bytes read is returned (zero indicates end of file)

  • On error, -1 is returned

A proposal :

/* you already check input and output file was open with success */

char buffer[buffer_size];

for(;;){
  ssize_t readable = read(sourcef, buffer, buffer_size);

  if(readable <= 0){
    close(sourcef);
    close(destf);
    if (readable != 0)
      /* not EOF */
      exit_with_usage("Could not read.");
    /* EOF */
    break;
  }

  if (write(destf, buffer, n) != n) {
    close(sourcef);
    close(destf);
    exit_with_usage("Could not write.");
  }
}

I suppose exit_with_usage calls exit() so does not return

Note in theory write may write less than the expected number of characters without being an error, and the write has to be done in a loop, but in that case it is useless to manage that

read function returns how many bytes were read to buffer(which has buffer_size). Its not always the case actual bytes read has same value as buffer size(consider scenario if there are not enough bytes left in source file to fully fill your buffer). So you should write to destination file not buffer_size(third argument of the write function), but how many bytes have you read - that is readable variable in your code

You should exit when readable returns an error.So

while(readable != 0){

should be

while(readable != -1){

So that loop could be terminataed when an readfile is exhausted.

You see currently after the whole readfile has been read, calling read fails but write is being called repeatedly since execution has no exit path for failure on read. Also write should only write the number of bytes read. So the code would look like this:

char buffer[buffer_size];

int readable=1;
int writeable;
while(readable != -1){
    readable = read(sourcef, buffer, buffer_size);
    if(readable == -1){
        close(sourcef);
        close(destf);
        exit_with_usage("Could not read.");
    }
    writeable = write(destf, buffer, readable);
    if(writeable == -1){
        close(sourcef);
        close(destf);
        exit_with_usage("Could not write.");
    }
}

Simple code

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // For system calls write, read e close
#include <fcntl.h>

#define BUFFER_SIZE 4096

int main(int argc, char* argv[]) {
    if (argc != 3) {
        printf("Usage %s Src_file Dest_file\n", argv[0]);
        exit(1);
    }
    
    unsigned char buffer[BUFFER_SIZE] = {0};
    ssize_t ReadByte = 0;
    
    int src_fd, dst_fd;
    
    // open file in read mode
    if ((src_fd = open(argv[1], O_RDONLY)) == -1) {
        printf("Failed to open input file %s\n", argv[1]);
        exit(1);
    }
    
    // open file in write mode and already exists to overwrite
    if ((dst_fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 644)) == -1) {
        printf("Failed to create output file %s\n", argv[2]);
        exit(1);
    }
    
    // loop
    while (1) {
        // read buffer
        ReadByte = read(src_fd, buffer, sizeof(buffer));
        // error with reading
        if (ReadByte == -1) {
            printf("Encountered an error\n");
            break;
        } else if (ReadByte == 0) {
            // file end exit loop
            printf("File copying successful.\n");
            break;
        }
        
        // error with writing
       if (write(dst_fd, buffer, ReadByte) == -1) {
        printf("Failed to copying file\n");
          break;
       }
    
    }
    
    // Close file
    close(src_fd);
    close(dst_fd);
    
    exit(0);
}

Run

./program src_file dest_file

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM