Go – Korrekte Verwendung von Multipart Part.Read

王林
Freigeben: 2024-02-09 08:18:27
nach vorne
1035 Leute haben es durchsucht

Go - 多部分 Part.Read 的正确用法

Der PHP-Editor Xinyi stellt Ihnen heute die korrekte Verwendung der mehrteiligen Part.Read-Sprache in Go vor. Bei der Verarbeitung von HTTP-Anfragen stoßen wir häufig auf Situationen, in denen wir mehrere Teile von Daten lesen müssen, beispielsweise beim Verarbeiten von Datei-Uploads. Das net/http-Paket der Go-Sprache stellt die Part.Read-Methode zum Lesen mehrteiliger Daten bereit, aber viele Entwickler werden bei der Verwendung auf einige Probleme stoßen. In diesem Artikel wird die korrekte Verwendung von Part.Read ausführlich erläutert, um Entwicklern dabei zu helfen, mehrteilige Daten besser zu verarbeiten und die Programmstabilität und -leistung zu verbessern. Lass uns einen Blick darauf werfen!

Frageninhalt

Ich habe versucht, multipart.part zu verwenden, um das Lesen von http für sehr große Datei-Uploads (>20 GB) zu erleichtern – also habe ich den folgenden Code geschrieben und er scheint gut zu funktionieren:

func ReceiveMultipartRoute(w http.ResponseWriter, r *http.Request) {
    mediatype, p, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
    if err != nil {
       //...
    }
    if mediatype != "multipart/form-data" {
        //...
    }
    boundary := p["boundary"]
    reader := multipart.NewReader(r.Body, boundary)
    buffer := make([]byte, 8192)
    for {
        part, err := reader.NextPart()
        if err != nil {
            // ... 
        }
    
        f, err := os.CreateTemp("", part.FileName())
        if err != nil {
            // ...
        }
    
        for {
            numBytesRead, err := part.Read(buffer)
            // People say not to read if there's an err, but then I miss the last chunk?
            f.Write(buffer[:numBytesRead])
            if err != nil {
                if err == io.EOF {
                    break
                } else {
                    // error, abort ...
                    return
                }
            }
        }
    }
}

Nach dem Login kopieren

In der innersten for-Schleife stellte ich jedoch fest, dass ich aus part.read lesen musste, bevor ich eof überprüfte, weil mir aufgefallen war, dass ich den letzten Block verpassen würde, wenn ich dies vorher tun und kaputtgehen würde. Allerdings ist mir in vielen anderen Artikeln/Beiträgen aufgefallen, dass die Leute nach Fehlern/eof suchen und gegebenenfalls nach break-ing suchen, ohne den letzten Lesevorgang zu verwenden. Verwende ich multipart.part.read() falsch/sicher?

Workaround

Sie nutzen multipart.part richtig.

multipart.part ist eine spezifische < Implementierung von go.dev/io#reader" rel="nofollow noreferrer">io.reader. Daher sollten Sie sich an die Konvention halten und den Empfehlungen von io folgen. Leser. Zitiert aus der Dokumentation:

Aufrufer sollten immer zurückgegebene n > 0 Bytes verarbeiten, bevor sie den Fehler err in Betracht ziehen. Dies ermöglicht die korrekte Behandlung von E/A-Fehlern, die nach dem Lesen einiger Bytes auftreten, sowie das zulässige EOF-Verhalten.

Beachten Sie außerdem, dass Sie im Beispiel Daten von io.reader nach os.file kopieren. os.file implementiert die io.readerfrom-Schnittstelle, sodass Sie Daten mit der Methode file.readfrom() kopieren können.

_, err := file.readfrom(part)
// non io.eof
if err != nil {
    return fmt.errorf("copy data: %w", err)
}
Nach dem Login kopieren

Wenn Sie einen Puffer verwenden müssen, können Sie die Funktion io.copybuffer() verwenden. Beachten Sie jedoch, dass Sie die io.readerfrom-Implementierung ausblenden müssen, da der Puffer sonst nicht zum Durchführen des Kopiervorgangs verwendet. Siehe Beispiele: 1, 2, 3.

_, err := io.CopyBuffer(writeFunc(file.Write), part, buffer)
// non io.EOF
if err != nil {
    return fmt.Errorf("copy data: %w", err)
}

type writeFunc func([]byte) (int, error)

func (write writeFunc) Write(data []byte) (int, error) {
        return write(data)
}
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonGo – Korrekte Verwendung von Multipart Part.Read. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!