Wovon ich süchtig war, als ich mit riesigen Dateien in einer Linux 32-Bit-Umgebung umging

Ich könnte eines Tages wieder süchtig danach sein, also ein Memorandum

Ich war süchtig nach

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 ...

Lösung

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!

Extra: Meine Lösung, die in Bezug auf Glibc nachsichtig war

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! ** **.

Bewältigung

Ö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.

Betrachtung

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

Wovon ich süchtig war, als ich mit riesigen Dateien in einer Linux 32-Bit-Umgebung umging
Wovon ich beim Erstellen von Webanwendungen in einer Windows-Umgebung abhängig war
Was ich mit json.dumps in Pythons base64-Codierung süchtig gemacht habe
Ein Hinweis, von dem ich süchtig war, als ich unter Linux einen Piepton machte
Ein Hinweis, dem ich beim Erstellen einer Tabelle mit SQL Alchemy verfallen war
Als ich versuchte, PIL und matplotlib in einer virtuellen Umgebung zu installieren, war ich süchtig danach.
Ich war süchtig danach, eine Python-Venv-Umgebung mit VS Code zu erstellen
Als ich Django in mein Home-Verzeichnis legte, wurde ich mit einem Berechtigungsfehler in eine statische Datei eingebunden
Ich war süchtig danach, 2020 mit Selen (+ Python) zu kratzen
Ein Hinweis, dem ich beim Ausführen von Python mit Visual Studio Code verfallen war
Eine Geschichte, der ich nach der SFTP-Kommunikation mit Python verfallen war
Wovon ich süchtig war, als ich Python Tornado benutzte
Wovon ich süchtig war, als ich Klassenvererbung und gemeinsame Tabellenvererbung in SQLAlchemy kombinierte
Was ich getan habe, als ich wütend war, es mit der Option enable-shared einzufügen
Wovon ich süchtig war, als der Processing-Benutzer zu Python wechselte
Eine Geschichte, nach der ich süchtig war, als ich in Go nil als Funktionsargument angab
Wovon ich süchtig war, als ich ALE in Vim für Python einführte
Was ich süchtig nach Python Autorun war
Als ich versuchte, mithilfe von Anforderungen in Python zu kratzen, war ich süchtig nach SSLError, also einem Workaround-Memo
Eine Geschichte, die mich süchtig nach dem Versuch machte, LightFM unter Amazon Linux zu installieren
Eine Geschichte, die ich süchtig danach war, eine Video-URL mit Tweepy zu bekommen
Wovon ich in Kapitel 3 der kollektiven Intelligenz abhängig war. Es ist kein Tippfehler, daher denke ich, dass etwas mit meinem Code nicht stimmt.
Ich war süchtig danach, Cython mit PyCharm auszuprobieren, also machen Sie sich eine Notiz
[Python] Als ich versuchte, ein Dekomprimierungswerkzeug mit einer Zip-Datei zu erstellen, die ich gerade kannte, war ich süchtig nach sys.exit ()
Zeichenkodierung beim Umgang mit Dateien in Python 3
Als ich versuchte, mit Python eine virtuelle Umgebung zu erstellen, funktionierte dies nicht
Drei Dinge, von denen ich süchtig war, als ich Python und MySQL mit Docker verwendete
Ich habe keine Angst, eine Programmierumgebung aufzubauen.
Als ich in IPython versuchte, den Wert zu sehen, war es ein Generator, also kam ich auf ihn, als ich frustriert war.
Ich habe untersucht, welche Berechtigungen zum Löschen von Linux-Dateien erforderlich sind.
Was tun, wenn gdal_merge eine große Datei generiert?
Ich möchte mit einem Roboter in Python arbeiten.
pickle Um zu lesen, was in 2 Serien mit 3 Serien gemacht wurde
Eine Geschichte, von der ich bei np.where süchtig war
Ich war süchtig danach, logging.getLogger mit Flask 1.1.x zu versuchen
Ich war nüchtern süchtig danach, awscli von einem in crontab registrierten Python 2.7-Skript aus aufzurufen
Beachten Sie, dass ich süchtig nach dem npm-Skript war, das in der Überprüfungsumgebung nicht übergeben wurde
Ich habe versucht, eine Umgebung mit WSL + Ubuntu + VS-Code in einer Windows-Umgebung zu erstellen
Ich blieb stecken, als ich versuchte, einen relativen Pfad mit relative_to () in Python anzugeben
Praktische Linux-Tastaturbedienung, die ich mir selbst beibringen möchte, als ich in der Schule war
Ich habe versucht, eine Klasse für die Suche nach Dateien mit der Glob-Methode von Python in VBA zu erstellen
Dinge, die Sie bei der Implementierung von Airflow mit Docker-Compose beachten sollten
[IOS] GIF-Animation mit Pythonista3. Ich war süchtig danach.
Erstellen Sie Azure-Pipelies mit Azure DevOps in einer selbst gehosteten Linux-Umgebung
Ich möchte eine Jupyter-Umgebung mit einem Befehl starten
Ich möchte eine virtuelle Umgebung mit Jupyter Notebook verwenden!
Memo (März 2020), dem ich bei der Installation von Arch Linux auf dem MacBook Air 11'Early 2015 verfallen war
Was wurde gefragt, wenn Random Forest in der Praxis verwendet wurde?
Worüber ich mir Sorgen gemacht habe, als ich Bilder mit matplotlib angezeigt habe
Wovon ich süchtig war, als ich mein eigenes neuronales Netzwerk mit den Gewichten und Vorurteilen aufbaute, die ich mit dem MLP-Klassifikator von scikit-learn bekam.
Ich habe eine Umgebung von der Centos-Installation bis zur Erweiterung der PHP-Quelle unter Linux erstellt, aber was tun, wenn ein Browserfehler auftritt?
Beachten Sie, dass ich süchtig danach war, mit Pythons mysql.connector über eine Webanwendung auf die Datenbank zuzugreifen
Eine Geschichte, die nicht funktioniert hat, als ich versucht habe, mich mit dem Python-Anforderungsmodul anzumelden
Was tun, wenn pip --user in einer mit pyenv erstellten virtuellen Umgebung einen Fehler zurückgibt?
So zeigen Sie eine bestimmte Dateispalte unter Linux an (awk)