Reed
Reed

Reputation: 1261

write() doesn't write the data

I want to copy file1 content to file2, but after the write command file2 is still empty.

int fd1;
int fd2;
size_t len;
size_t nbytes;
ssize_t bytes_read;

fd1 = open(file1, O_RDWR);

fd2 = open(file2, O_WRONLY | O_CREAT | O_TRUNC, 0644 );
char *buf[len];

nbytes = sizeof(buf);
bytes_read = read(fd1, buf, nbytes);

write(fd2, &bytes_read, nbytes); 

close(fd1);
close(fd2);

return 0;

Is there something bad with this line?

char *buf[len];

Should I use malloc or memset instead?

Upvotes: 0

Views: 211

Answers (2)

user3629249
user3629249

Reputation: 16540

the following proposed code:

  1. cleanly compiles
  2. checks for and handles errors
  3. corrects the problems listed in the comments to the question
  4. Note: this assumes file names are from command line arguments

and now the code

#include <stdio.h>   // perror(), printf()
#include <stdlib.h>  // exit(), EXIT_FAILURE

#include <sys/types.h>  // open()
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>     // write(), close(), read()

#define MAX_BUF_LEN 1024

int main( int argc, char *argv[] )
{
    int fd1;
    int fd2;

    ssize_t bytes_read;

    if( 3 != argc )
    {
        fprintf( stderr, "USAGE: %s inputFileName outputFileName\n", argv[0] );
        exit( EXIT_FAILURE );
    }

    if( 0 > (fd1 = open( argv[1], O_RDONLY)) )
    {
        perror( "open for input file failed" );
        exit( EXIT_FAILURE );
    }


    if( 0 > (fd2 = open( argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644 )) )
    {
        perror( "open for output file failed" );
        close( fd1 );  // cleanup
        exit( EXIT_FAILURE );
    }


    char buf[ MAX_BUF_LEN ];


    while( (bytes_read = read( fd1, buf, MAX_BUF_LEN )) )
    {
        if( 0 > bytes_read )
        { // then read error event
            perror( "read failed" );
            break;  // exit while() loop
        }

        else
        {
            // EDIT: following line incorrect.
            //ssize_t bytes_written = write( fd2, &bytes_read, (size_t)bytes_read );
            // corrected line:
            ssize_t bytes_written = write( fd2, buf, (size_t)bytes_read );

            if( bytes_read != bytes_written )
            { // then write error event
                fprintf( stderr, "bytes read: %ld, bytes written: %ld\n", bytes_read, bytes_written );
                break; // exit while() loop
            }
        }
    } // end while()

    close(fd1);
    close(fd2);

    return 0;
} // end function: main

Upvotes: 1

P.A
P.A

Reputation: 821

You can try this program:

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

int main(int argc, char* argv[])
{
  int fd1, fd2;
  size_t len, nbytes;
  ssize_t bytes_read;
  struct stat st;

  fd1 = open("./file1.txt", O_RDWR);

  if ((fd1 != -1) &&(fstat(fd1, &st) == 0)) {
        len = st.st_size;
      }

  fd2 = open("./file2.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644 );

  char buf[len];
  nbytes = sizeof(buf);

  if((fd1 != -1) && (fd2 != -1)){
    bytes_read = read(fd1, buf, nbytes);
    write(fd2, buf, nbytes);
    close(fd1);
    close(fd2);
  }else {
    printf("error \n");
    exit(-1);
  }

  return 0;

}

You should change the buf from char *buf[len] to char buf[len] and to get the length of file1 you can use these instructions:

fseek(fp, 0L, SEEK_END);
len = ftell(fp);

Before using buf, try to use memset.

Upvotes: 4

Related Questions