Re: Einlesen aus Datei > 2GB

Christian Schneider <[email protected]>
Newsgroups gmane.linux.suse.programming
Message-ID <[email protected]>
Hallo!

Am Samstag, 4. Juni 2005 06:38 schrieb David Haller:
[C-Code]
> Achtung: ich habe das jetzt noch in der Mail etwas veraendert, kann
> sein, dass da Fehler drin sind.

Funktioniert. Die Ausgabe war wie in deinen Kommentaren.

Der Compiler hat übrigens bei (off_t)2247483648 gemeckert:
Warnung: this decimal constant is unsigned only in ISO C90
Aber das macht wohl nichts.

> Aufpassen muss man nur, dass man nicht in die "sparse-file" Falle
> laeuft, wo AFAIK Fehler auftreten, wenn die Datei "echt" ueber 2 GB
> gross wird, d.h. man muesste > 2 GB schreiben...

Das ist kein Problem (hier war die Datei echt > 2GB):

==============
#define _LARGEFILE_SOURCE
#define _FILE_OFFSET_BITS 64
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(void) {
    int fd;
    char bigname[] = "/tmp/bigfile"; /* 2147484672 bytes */

    printf("sizeof(off_t) = %i\n", sizeof(off_t)); /* should be 8 */

    fd = open(bigname, O_RDONLY);

    if( fd ) {
        /* seek to over 2 GB, this should be lseek64, just as off_t is
           off64_t */
        off_t offset = lseek(fd, (off_t)-2, SEEK_END);

        printf("lseek = %Lu\n", offset); /* should be 2147484670 (?) */

        if(offset == (off_t)-1) {
            perror("");
            close(fd);
            exit(errno);
        }

        {
            ssize_t reads = read(fd, bigname, 2);
            perror(""); /* should be "Success" */
            printf("read() = %i\n", reads); /* should be 2 */
        }
        close(fd);
    } else {
        perror("");
        exit(errno);
    }
    return 0;
}
==============

Ausgabe:
sizeof(off_t) = 8
lseek = 2147484670
Success
read() = 2

Ich hatte auch mit C++ das Öffnen der Datei mit einem Sparse-File 
überprüft und bei größer 2GB gehts schief. Scheinbar ist es egal, ob 
die Datei sparse ist oder nicht.

> Achso, du koenntest auch ein C-Proggie auf ne vorhandene Datei
> loslassen... (im Prinzip 'open' statt dem 'mkstemp' und 'read' statt
> 'write' nach dem lseek oben (da musst du aber dem read noch nen
> Buffer anlegen). Und natuerlich kein "unlink" (auch bei der
> Fehlerbehandlung nicht) ;)

s.o.

> Bei mir klappt das uebrigens nicht, ich bekomme da
>
>     SIGXFSZ (File size limit exceeded)
>
> und nen coredump.

Bei mir gehts gut. :-)

Was nun?

Gruß,
Christian


-- 
Um die Liste abzubestellen, schicken Sie eine Mail an:
    [email protected]
Um eine Liste aller verfügbaren Kommandos zu bekommen, schicken
Sie eine Mail an: [email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.