2008-10-02 8 views
19

fopen schlägt fehl, wenn ich versuche, eine sehr moderat große Datei in PHP einzulesen. A 6 meg file macht es ersticken, obwohl kleinere Dateien um 100k sind in Ordnung. Ich habe gelesen, dass es manchmal notwendig ist, PHP mit dem -D_FILE_OFFSET_BITS=64 Flag zu rekompilieren, um Dateien über 20 Gigs oder etwas lächerlich zu lesen, aber sollte ich keine Probleme mit einer 6-Megabyte-Datei haben? Schließlich wollen wir Dateien lesen, die etwa 100 MB groß sind, und es wäre schön, sie öffnen zu können und dann Zeile für Zeile mit Fgets durchzulesen, wie ich es mit kleineren Dateien machen kann.Das Lesen sehr großer Dateien in PHP

Was sind Ihre Tricks/Lösungen zum Lesen und Ausführen von Operationen an sehr großen Dateien in PHP?

Update: Hier ist ein Beispiel für einen einfachen Codeblock, der auf meiner 6-Megapixel-Datei fehlschlägt - PHP scheint keinen Fehler zu werfen, es gibt nur false zurück. Vielleicht mache ich etwas extrem dummes?

Ein weiteres Update: Vielen Dank für Ihre Hilfe, es erwies sich als etwas unglaublich dumm - ein Problem mit Berechtigungen. Meine kleine Datei hatte unerklärlicherweise Leseberechtigungen, wenn die größere Datei dies nicht tat. Do!

+0

Versuchen Sie, nur durch die Datei zu übergeben? dh. Herunterladen? Oder parst du tatsächlich die Daten in den Dateien für einen bestimmten Zweck? Danke. – DreamWerx

+0

sollte es nicht fehlschlagen, ohne eine Warnung/einen Fehler zu erzeugen. Bitte schalten Sie alle Fehler mit error_reporting (E_ALL) ein und stellen Sie sicher, dass display_errors aktiviert ist, um sie in Ihrem Browser anzuzeigen, oder überprüfen Sie das Fehlerprotokoll Ihres Webserver. –

Antwort

36

Sind Sie sicher, dass es fopen ist, dass Ihr Skript ist versagt und nicht die Timeout-Einstellung? Der Standardwert liegt normalerweise bei etwa 30 Sekunden. Wenn Ihre Datei länger als diese Zeit zum Einlesen benötigt, stürzt sie möglicherweise ab.

Eine andere Sache, die Sie berücksichtigen sollten, ist das Speicherlimit Ihres Skripts - das Lesen der Datei in ein Array kann dazu führen. Überprüfen Sie daher Ihr Fehlerprotokoll auf Speicherwarnungen.

Wenn keines der oben genannten Probleme Ihr Problem ist, können Sie unter Verwendung von fgets die Datei zeilenweise lesen und so weiterverarbeiten.

$handle = fopen("/tmp/uploadfile.txt", "r") or die("Couldn't get handle"); 
if ($handle) { 
    while (!feof($handle)) { 
     $buffer = fgets($handle, 4096); 
     // Process buffer here.. 
    } 
    fclose($handle); 
} 

bearbeiten

PHP scheint nicht einen Fehler zu werfen, es gibt nur falsch.

Ist der Pfad zu $rawfile korrekt in Bezug auf wo das Skript ausgeführt wird? Versuchen Sie vielleicht, hier einen absoluten Pfad für den Dateinamen anzugeben.

+3

Es ist nur möglich, wie man wirklich große Dateien öffnet. Ich verarbeite mit dieser Lösung 1.5GB Datei ohne jedes Problem. Alle anderen Lösungen wie file_get_contents der Datei lesen die ganze Datei in den Speicher. Dieser Ansatz wird Zeile für Zeile verarbeitet. – StanleyD

+0

Warum 4096 bedeutet eine Zeile? – Phoenix

+0

@Phoenix 4096 bedeutet, lesen Sie höchstens 4096 - 1 Bytes, wenn keine Zeilenumbrüche auftreten. Überprüfen Sie das Handbuch. – a3f

0

Nun, Sie könnten versuchen, die Readfile-Funktion zu verwenden, wenn Sie nur die Datei ausgeben möchten.

Wenn dies nicht der Fall ist - vielleicht sollten Sie über das Design der Anwendung nachdenken, warum möchten Sie solche großen Dateien auf Web-Anfragen öffnen?

+0

Wir müssen das Hinzufügen großer Datenmengen automatisieren, damit große CSV-Dateien vom Benutzer hochgeladen und von der Anwendung analysiert und in die Datenbank integriert werden können. Ich würde gerne andere Vorschläge für den Ansatz, wenn Sie denken, dass das Lesen und Parsen hochgeladener Dateien mit PHP ist nicht der beste Weg zu gehen. –

+0

Ich würde nicht denken, PHP hätte ein Problem mit 6MB CSV-Dateien? Scheint wie eine klein genug Datei für sie zu handhaben. Wie in den Kommentaren oben, bitte posten Sie den genauen Fehler/und oder Code. Könnte ein Speicherfehler dein Schlagen sein? Oder eine max_execution_time? Wir brauchen mehr Informationen um zu helfen. – DreamWerx

1

Ich habe Fopen verwendet, um Videodateien zum Streamen zu öffnen, mit einem PHP-Skript als Video-Streaming-Server, und ich hatte kein Problem mit Dateien mit einer Größe von mehr als 50/60 MB.

0

Wenn das Problem durch das Erreichen des Speicherlimits verursacht wird, können Sie versuchen, einen höheren Wert einzustellen (dies kann je nach php-Konfiguration funktionieren oder nicht).

dies das Speicherlimit bis 12 Mb setzt

ini\_set("memory_limit","12M"); 
+2

Hinweis: Während dies helfen kann, verschiebt es nur das Problem: Sobald eine 15 MB-Datei kommt In, kommt das Problem zurück. (Wenn Ihre Dateien nie eine bestimmte Grenze überschreiten, kann das Problem verschwinden.) – Piskvor

0

für mich, fopen() mit Dateien über 1 MB sehr langsam war, file() ist viel schneller. Nur versuchen, Zeilen 100 zu einer Zeit zu lesen und Stapeleinfügungen zu erstellen, dauert fopen() dauert 37 Sekunden vs Datei() dauert 4 Sekunden. Muss sein, dass String-> Array-Schritt in Datei()

Ich würde versuchen, alle Datei-Handling-Optionen zu sehen, welche am besten in Ihrer Anwendung funktioniert.

5

Did 2 Tests mit einer 1,3 GB-Datei und einer 9.5GF Datei

1,3

Mit fopen()

Dieser Prozess 15555 ms für seine Berechnungen verwendet.

Es verbrachte 169 ms in System

Mit file()

für seine Berechnungen Dieser Prozess verwendet 6983 ms aufruft.

Es 4.469 ms in System ausgegeben ruft

9.5GB

Mit fopen()

Dieser Prozess 113559 ms für seine Berechnungen verwendet

Es 2.532 ms in System ausgegeben ruft

Verwenden file()

Dieser Prozess verwendet 8221 ms für seine Berechnungen

Es verbrachte 7998 ms in Systemaufrufe

Scheint file() schneller ist

Verwandte Themen