2017-04-23 6 views
-1

Ich habe Probleme beim Überschreiben von Dateien mit Nullen. Das Problem besteht darin, dass das letzte Byte der ursprünglichen Datei erhalten bleibt, selbst wenn ich die Größe um 100 Byte überschreite. Hat jemand eine Idee, was ich vermisse?Probleme beim Überschreiben von Dateiinhalt

func (h PostKey) ServeHTTP(w http.ResponseWriter, r *http.Request) { 
    f, err := os.Create("received.dat") 
    if err != nil { 
     w.WriteHeader(http.StatusInternalServerError) 
     return 
    } 
    defer f.Close() 

    _, err = io.Copy(f, r.Body) 
    if err != nil { 
     w.WriteHeader(http.StatusInternalServerError) 
     return 
    } 

    // Retrieve filesize 
    size, _ := f.Seek(0, 1) 
    zeroFilled := make([]byte, size + 100) 
    n, err := f.WriteAt(zeroFilled, 0) 
    if err != nil { 
     return 
    } 

    fmt.Printf("Size: %d\n", size) // prints 13 
    fmt.Printf("Bytes written: %d\n", n) // prints 113 
} 
+2

Können Sie vielleicht den Inhalt des Körpers teilen? Und was ist das letzte Byte, das nicht überschrieben wird? Mit Ihrem Code scheint es mir nicht möglich zu sein, Ihr Problem neu zu erstellen. [Hier ist der Spielplatz] (https://play.golang.org/p/0mASED0hSs) – mkopriva

+0

Sie haben keinen Code zur Verfügung gestellt, um das Problem zu reproduzieren. Fragen, die Debugging-Hilfe suchen ("Warum funktioniert dieser Code nicht?") Müssen das gewünschte Verhalten, ein spezifisches Problem oder einen Fehler und den kürzesten Code enthalten, der für die Reproduktion in der Frage erforderlich ist. – peterSO

Antwort

0

Ich schrieb in die Datei und versuchte, sie im selben Kontext zu überschreiben, und so waren Teile der ersten Schreiboperation noch im Speicher und noch nicht auf die Festplatte geschrieben. Durch Verwendung von f.Sync(), um alles nach dem Kopieren des Bodys-Inhalts zu löschen, konnte ich das Problem beheben.

1

Das Problem trat auf, weil die Daten in eine Datei gleiche (gemeinsame Ressource) innerhalb eines HTTP-Handler geschrieben werden, und der Handler selbst gleichzeitig ausgeführt werden kann. Sie müssen den Zugriff auf die Datei während der Datenserialisierung sperren (Überschreiben). Schnelle Lösung wird sein:

import (
    "sync" 
    //... other packages 
) 

var muFile sync.Mutex 

func (h PostKey) ServeHTTP(w http.ResponseWriter, r *http.Request) { 
    muFile.Lock() 
    defer muFile.Unlock() 

    f, err := os.Create("received.dat") 
    //other statements 
    //... 
} 

Wenn Ihr Serverlast gering ist, wird die obige Lösung in Ordnung sein. Wenn Ihr Server jedoch viele Anfragen gleichzeitig verarbeiten muss, müssen Sie einen anderen Ansatz verwenden (obwohl die Regel identisch ist, sperren Sie den Zugriff auf eine freigegebene Ressource).

Verwandte Themen