Thread: File reading and writing

  1. #16
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    re: CPP vs C in using malloc...

    C++ is a bit more strict where void* are concerned. C doesn't require a cast, like you've noticed, C++ does. Since it ends in .cpp, the compiler assumes it's C++ code.

    Quzah.
    Hope is the first step on the road to disappointment.

  2. #17
    Registered User
    Join Date
    Sep 2001
    Posts
    752
    You know, I can't help but wonder what exactly you want to do with these files?
    Callou collei we'll code the way
    Of prime numbers and pings!

  3. #18
    Code Warrior
    Join Date
    Nov 2001
    Posts
    669
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    struct file{
    	char *p;
    };
    
    int main(void){
    	FILE *in, *out;
    	struct file f;
    	in = fopen("c:\\windows\\desktop\\in.txt", "r");
    	out = fopen("c:\\windows\\desktop\\out.txt", "w");
    
    	f.p = (char *)malloc(10 * sizeof(f.p));
    
    	fread(f.p, 10, 1, in);
    	fwrite(f.p, 10, 1, out);
    
    	return EXIT_SUCCESS;
    }
    I tried this, and it is not working. Why not?
    Current projects:
    1) User Interface Development Kit (C++)
    2) HTML SDK (C++)
    3) Classes (C++)
    4) INI Editor (Delphi)

  4. #19
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Because it's horrible?

    int c;
    while( (c=fgetc(fin)) != EOF ) fputc( c, fout );

    Or did you want the real reason?

    Check your values to make sure your files have actually opened correctly. Use printf() to see what you've read first. This way you can track down your problem.

    Quzah.
    Hope is the first step on the road to disappointment.

  5. #20
    Code Warrior
    Join Date
    Nov 2001
    Posts
    669
    Code:
    int c; 
    while( (c=fgetc(fin)) != EOF ) fputc( c, fout );
    This code is slow!

    I know how to copy files. Three days ago I created a file splitter. It's easy, but it's slow. I tested with 300 MB large file and I split it on 3 parts (100 MB). The program was working on this about 7 minutes. That's why I want to learn how to copy with pointers (malloc). So, please help me with that.
    Last edited by GaPe; 12-30-2001 at 01:49 PM.
    Current projects:
    1) User Interface Development Kit (C++)
    2) HTML SDK (C++)
    3) Classes (C++)
    4) INI Editor (Delphi)

  6. #21
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    When you copy a file, everything in that file gets copied, so speed is difficult. Breaking the file into parts for copying is good because it keeps your program from choking (for the most part). You tried it with a 300Mb file and it took about 7 minutes, this sounds about right for copying a retail program of 300Mb from a CD to hard disk.

    You can move the data with pointers, but you're still moving the data. Pointers won't speed up the throughput of your computer, they will help with the efficiency of the program, but not the data.

    You know what the most common way of dealing with slow copying is? Hiding it with pictures and status bars and little rotating hour glasses that tell the user the computer has not in fact frozen AND keeps them interested enough to not terminate the program.

    -Prelude
    Last edited by Prelude; 12-30-2001 at 01:55 PM.
    My best code is written with the delete key.

  7. #22
    Code Warrior
    Join Date
    Nov 2001
    Posts
    669
    But what about Windows Commander command "Split File". I tested with the same file (300 MB) and it took about 30 seconds.
    Why?

    And Prelude, please tell me why your code for copying files is not working.
    Last edited by GaPe; 12-30-2001 at 03:04 PM.
    Current projects:
    1) User Interface Development Kit (C++)
    2) HTML SDK (C++)
    3) Classes (C++)
    4) INI Editor (Delphi)

  8. #23
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >I tested with the same file (300 MB) and it took about 30 seconds. Why?
    Not a clue, when you find out be sure to let me know though

    If you're using it exactly as I wrote it then you're probably transferring too little data. Create a variable to hold the size of your file and replace every reference to 10 with that variable. In that example program I was only copying 10 bytes because that was the size of my test file.

    -Prelude
    My best code is written with the delete key.

  9. #24
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    In order to speed things up, you need to read/write much larger blocks of data - one char at a time is simply too expensive.

    Here's my idea
    Code:
    #include <stdio.h>
    #include <time.h>
    
    #define FRAGMENT_SIZE   (10*1000*1000L)     // size of file fragments
    
    int main ( ) {
        char buff[BUFSIZ];
        FILE *in, *out = NULL;
        long int num_blocks = FRAGMENT_SIZE / BUFSIZ;
        long int remainder  = FRAGMENT_SIZE % BUFSIZ;
        long int count = 0;
        int      num_out_files = 0;
        size_t   read_size;
        clock_t  start, end;
    
        start = clock();
        in = fopen( "f:in.dat", "rb" );
        while ( !feof(in) ) {
            // determine the maximum amount of data to read
            if ( count == num_blocks ) {
                read_size = remainder;
            } else {
                read_size = BUFSIZ;
            }
    
            // read/write that amount - the actual amount to write
            // depends on the actual amount read, which will be less than
            // read_size at the end of the in file
            read_size = fread( buff, 1, read_size, in );
            if ( read_size != 0 ) {
                if ( count == 0 ) {
                    char filename[50];
                    if ( out != NULL ) {            // close previous file
                        fclose( out );
                    }
                    sprintf( filename, "f:out%03d.dat", num_out_files++ );
                    out = fopen( filename, "wb" );  // open next file
                }
                fwrite( buff, 1, read_size, out );  // should check result...
            }
    
            // determine if we need to read more blocks to fill the current
            // out file, or start a new out file
            if ( count == num_blocks ) {
                count = 0;
            } else {
                count++;
            }
        }
        if ( out != NULL ) {
            fclose( out );
        }
        end = clock();
        printf( "Splitting took %d seconds\n",
                (end-start)/CLOCKS_PER_SEC );
        return 0;
    }
    BUFSIZ is supposed to be optimal for average use, but you might like to experiment with other values, particularly those which are multiples of the basic block size on your file system (eg. 512 bytes), or perhaps the cluster size.

  10. #25
    Code Warrior
    Join Date
    Nov 2001
    Posts
    669
    Salem

    I see that you use the "!feof(fin)". Whenever I used this it has never read a whole file, always was some KB's left.

    Salem, can YOU tell me why Windows Commander Split file takes only 30s to complete with splitting a 300 MB large file?
    Current projects:
    1) User Interface Development Kit (C++)
    2) HTML SDK (C++)
    3) Classes (C++)
    4) INI Editor (Delphi)

  11. #26
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > Whenever I used this it has never read a whole file, always was some KB's left
    Perhaps posting some code so we can see how YOU use feof() would help determine why.

    > why Windows Commander Split file takes only 30s to complete with splitting a 300 MB large file?
    Because it uses the same mechanism as I do - a large buffer.
    Did you try my code?

  12. #27
    Code Warrior
    Join Date
    Nov 2001
    Posts
    669

    Unhappy

    Yes, I tried. It's working .

    I have few questions:

    1) FRAGMENT_SIZE (10*1000*1000L)

    What that "L" means? And is this size in bytes?

    2) num_blocks = FRAGMENT_SIZE / BUFSIZ;
    remainder = FRAGMENT_SIZE % BUFSIZ;

    Why and for what do you need this?

    3) fread( buff, 1 (*Why just 1?*), read_size(*Why so many times?*), in );
    Current projects:
    1) User Interface Development Kit (C++)
    2) HTML SDK (C++)
    3) Classes (C++)
    4) INI Editor (Delphi)

  13. #28
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > What that "L" means?
    1000L means a long value, not short or int

    > Why and for what do you need this?
    because
    buff = malloc( FRAGMENT_SIZE );
    will probably fail if you're trying to split a file into 100MB blocks.
    So instead, use a fixed sized block, and work out how many times we need to read a full buffer (num_blocks) and the number of remainder bytes (remainder) to total FRAGMENT_SIZE

    FRAGMENT_SIZE = num_blocks * BUFSIZ + remainder;

    > 3) fread( buff, 1 (*Why just 1?*), read_size(*Why so many times?*), in );
    Read the manual

  14. #29
    Code Warrior
    Join Date
    Nov 2001
    Posts
    669
    Thank you Salem and happy new year!
    Current projects:
    1) User Interface Development Kit (C++)
    2) HTML SDK (C++)
    3) Classes (C++)
    4) INI Editor (Delphi)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. segmetation fault (reading and writing file in c)
    By tasosa in forum C Programming
    Replies: 5
    Last Post: 04-13-2009, 06:04 AM
  2. Reading out of and writing into the same file
    By Wiretron in forum C Programming
    Replies: 8
    Last Post: 12-30-2006, 02:04 PM
  3. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  4. file writing and reading
    By Micko in forum C Programming
    Replies: 8
    Last Post: 01-13-2004, 11:18 AM
  5. what does this mean to you?
    By pkananen in forum C++ Programming
    Replies: 8
    Last Post: 02-04-2002, 03:58 PM