Mailinglist Archive: opensuse-programming-de (97 mails)
| < Previous | Next > |
Re: Einlesen aus Datei > 2GB
- From: Christian Schneider <ch_schneider_hi@xxxxxxxxxx>
- Date: Sat, 4 Jun 2005 15:51:12 +0200
- Message-id: <200506041551.13155.ch_schneider_hi@xxxxxxxxxx>
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
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
| < Previous | Next > |