Ich könnte eines Tages wieder süchtig danach sein, also ein Memorandum
Ich entwickle immer noch in einer Linux 32-Bit-Umgebung, war aber süchtig nach einem bestimmten System. Das System verwaltet Dateien mit einem C-Sprachprogramm. Es kann eine Größe von mehreren GByte verarbeiten, und wenn ich es versuche, funktioniert es überhaupt nicht.
Da die Datei sehr groß ist, dauert es einige Zeit, sie einmal zu reproduzieren, und die Ursache, die ich beim Debuggen während des Frustrierens gefunden habe, ist sehr einfach.
** Die Datei ist zu groß zum Öffnen! ** **.
Es scheint, dass Linux 32bit etwa 2 GByte ist. (Vielleicht nur meine Umgebung Nun, es wird eine Obergrenze geben, aber auf was werden Sie tatsächlich stoßen ... Darüber hinaus ist in diesem System eine Anwendung für C-Sprachprogramme zum Teilen von Dateien. Es kann nicht einmal die Datei öffnen. Kann es nicht glauben ...
23.04.2018 Nachtrag Im Kommentar von @ angel_p_57 Ich habe gehört, dass es eine Kompilierungsoption namens ** _FILE_OFFSET_BITS ** gibt.
Nach der Manpage und dem OSS-Code, den ich hatte, habe ich CFLAGS Folgendes hinzugefügt, damit fopen so wie es ist sicher ausgeführt werden kann!
-D_FILE_OFFSET_BITS=64
Nein, es ist wunderbar, dass Sie das Verhalten mit nur einer Option ändern können: glibc!
Der Befehl ** split ** kam zu mir, nachdem ich verschiedene Methoden zum Aufteilen von Dateien untersucht hatte. Dies ist ein Befehl zum Teilen von Dateien unter Linux Nur der Split-Befehl funktionierte einwandfrei.
Wie sollen wir dann damit umgehen? Das Beste ist, sich den Inhalt der Aufteilung anzusehen, aber ich habe keine Zeit ** Erstellen Sie einen fopen Wrapper mit dem Befehl split! ** **.
Öffnen Sie IF anstelle von fopen. Wenn die Größe groß ist, teilen Sie sie mit / usr / bin / split auf und speichern Sie sie im Verzeichnis tmp → Zum Zeitpunkt des Freads, als ich während des Freads zum Ende ging, öffnete ich die nächste Datei und las die Fortsetzung.
//fopenのラッパー
void * large_freader_open(const char *path, unsigned long maxsize) {
//....
//サイズを見て、大きすぎたらseparate_fileでファイル分割
unsigned long fsize = get_size(path);
if(fsize<=maxsize) {
//same as fopen
handle->fp=fopen(path, "r");
handle->max_index=1;
} else {
//separate file and open file as order
separate_file(path, maxsize, handle);
handle->fp = freader_fopen(handle);
}
//..
// return gibt die interne Struktur anstelle von FILE * zurück
return handle;
//..
}
static void separate_file(const char *path, unsigned long maxsize, struct large_freader_s *handle) {
//...
//tmpディレクトリを取得してファイル分割
char name[FNAME_MAX];
get_current_dirname(handle, name, FNAME_MAX);
snprintf(cmd, sizeof(cmd), "/usr/bin/split -d --suffix-length=6 -b %lu %s %s", maxsize, path, name);
//...
}
//freadのラッパー
size_t large_freader_read(void * prt, size_t size,void * stream) {
//...
//普通にfreadして
size_t ret = fread(prt, 1, size, handle->fp);
if(ret == size) {
//read success, return normaly
return ret;
}
//サイズ分読んでないなら次のファイルに移動
freader_fclose(handle);
//move to next
handle->cur_index++;
//全ファイル読んでるなら終わり
if(IS_LAST_FILE(handle)) {
//finish to read
return ret;
}
//そうじゃないなら次をopenしてread
handle->fp = freader_fopen(handle);
if(handle->fp) {
ret += fread(((char *)prt)+ret, 1, size-ret, handle->fp);
}
return ret;
}
//内部でのfopen処理
static FILE * freader_fopen(struct large_freader_s *handle) {
//splitしたファイル名を取得してfopen。close時にはファイル削除します。
char dname[FNAME_MAX];
get_current_fname(handle, dname, FNAME_MAX);
return fopen(dname, "r");
}
Ich habe es über Nacht zu Hause erstellt und auf Github veröffentlicht. Ich wollte die Datei zum Zeitpunkt des Schreibens auch teilen, daher handelt es sich um eine Wrapper-Bibliothek zum Lesen / Schreiben. Jetzt, da -D_FILE_OFFSET_BITS = 64 ist, kann nur noch Schreiben verwendet werden ...
https://github.com/developer-kikikaikai/read_write_wrapper
Mein Heim-PC ist 64-Bit und ich konnte ihn nicht mit 32-Bit testen. Daher werde ich die Probleme beheben, die mir bei der Verwendung in einer anderen Umgebung aufgefallen sind.
23.04.2018 Nachtrag ・ Wenn etwas Unerwartetes passiert, überprüfen Sie zuerst die Kompilierungsoptionen auf etwas!
Andernfalls, ・ Da fopen nicht verwendet werden kann, ist es sehr unangenehm, popen → ls ausführen zu müssen, um die Größe zu erhalten. ・ Ich mache mir Sorgen um den Betrieb in einer 32-Bit-Umgebung ・ Es geht um die Grenze eines 32-Bit-Systems, also sollten Sie Ihr Bestes geben, oder? etc Sie müssen sich auf eine beschissene Lösung verlassen.
Recommended Posts