Golang File Upload Example – Handle files at Server Side

In the Golang File Upload Example, I covered how  to handle uploads efficiently in Golang is an indispensable skill for many web developers. This comprehensive tutorial will guide you through the process of uploading files using Golang and handling them on the server side.

If you are looking for sending files in Golang, check this article.

Golang File Upload Example

Introduction

Uploading files is a common functionality in web applications. In Golang, file upload and management are straightforward, thanks to the standard library packages ‘net/http’ and ‘multipart’.

Uploading Files in Golang

Begin by setting up a simple HTTP server that listens for incoming requests with a file. You’ll need to import the ‘net/http’ package and use the ‘http.HandleFunc’ and ‘http.ListenAndServe’ functions.

package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.HandleFunc("/upload", fileUploadHandler)
    http.ListenAndServe(":8080", nil)
}

func fileUploadHandler(w http.ResponseWriter, r *http.Request) {
    // handling code will go here
}

In the ‘fileUploadHandler’, use the ‘r.ParseMultipartForm’ method to parse the uploaded file. Then, you can access the file using ‘r.FormFile’.

func fileUploadHandler(w http.ResponseWriter, r *http.Request) {
    // The argument to ParseMultipartForm is the max memory size (in bytes)
    // that will be used to store the file in memory.
    r.ParseMultipartForm(10 << 20) // 10 MB

    file, header, err := r.FormFile("uploadFile")
    if err != nil {
        fmt.Fprintf(w, "upload error: %v", err)
        return
    }
    defer file.Close()
    
    // You can now handle the file (for example, saving it locally)
    // Output a successful response
    fmt.Fprintf(w, "File %s uploaded successfully", header.Filename)
}

Handling File Upload on the Server

Once you have the file data, it’s time to handle it. You can save it to the server, process it, or perform any necessary actions. Here’s an example of how to save the uploaded file to your local filesystem.

func fileUploadHandler(w http.ResponseWriter, r *http.Request) {
    // ...existing code...
    
    // Create a file on the server
    dst, err := os.Create("/path/to/destination/" + header.Filename)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    defer dst.Close()

    // Copy the uploaded file to the destination file
    if _, err := io.Copy(dst, file); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    fmt.Fprintf(w, "File %s uploaded and saved successfully", header.Filename)
}

Sample HTML File to upload a file

Here is a sample HTML file that actively demonstrates the process of uploading files using the POST method with the “multipart/form-data” content type. This HTML file contains the necessary form elements and attributes to facilitate uploads from the client’s browser to the server. By including the appropriate form structure and attributes, developers can create user-friendly interfaces for file uploads in web applications.

<!DOCTYPE html>
<html>
<body>

<h2>Upload File</h2>
<form action="http://localhost:8080/upload" method="post" enctype="multipart/form-data">
  Select file to upload:
  <input type="file" name="file" id="file">
  <input type="submit" value="Upload File" name="submit">
</form>

</body>
</html>

 

Complete Code for handling file uploads

package main

import (
    "fmt"
    "io"
    "net/http"
    "os"
)

func main() {
    http.HandleFunc("/upload", uploadFileHandler)

    fmt.Println("Server started on localhost:8080")
    http.ListenAndServe(":8080", nil)
}

func uploadFileHandler(w http.ResponseWriter, r *http.Request) {
    // Limit the size of the memory to 10MB
    r.ParseMultipartForm(10 << 20) // 10 MB

    file, handler, err := r.FormFile("file")
    if err != nil {
        fmt.Println("Error Retrieving the File")
        fmt.Println(err)
        w.WriteHeader(http.StatusInternalServerError)
        return
    }
    defer file.Close()

    fmt.Printf("Uploaded File: %+v\n", handler.Filename)
    fmt.Printf("File Size: %+v\n", handler.Size)
    fmt.Printf("MIME Header: %+v\n", handler.Header)

    // Create a file to write the uploaded content
    dst, err := os.Create(handler.Filename)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    defer dst.Close()

    // Copy the uploaded file to the created file on the filesystem
    if _, err := io.Copy(dst, file); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    fmt.Fprintf(w, "Successfully uploaded file: %s", handler.Filename)
}

 

Advanced Scenarios

You might also encounter situations where you need to upload multiple files at the same time or validate the file size and type before saving.

func fileUploadHandler(w http.ResponseWriter, r *http.Request) {
    // ... existing code ...

    // For multiple files, call `r.ParseMultipartForm` and then iterate through r.MultipartForm.File
    files := r.MultipartForm.File["uploadFiles"]
    for _, fHeader := range files {
        // Open the file
        file, err := fHeader.Open()
        if err != nil {
            // Handle error
        }
        defer file.Close()
        // Process each file similarly to the single file scenario
    }
    
    fmt.Fprintln(w, "All files uploaded and saved successfully")
}

Conclusive Summary

By now, you should have a clear understanding of how to handle “golang file upload” both for single and multiple files. With this foundation, you can now integrate file uploading capabilities into your Golang applications, ensuring robust handling and storage of user-provided files.

class=”yoast-text-mark”>class=”yoast-text-mark”>class=”yoast-text-mark”>class=”yoast-text-mark”>class=”yoast-text-mark”>class=”yoast-text-mark”>class=”yoast-text-mark”>class=”yoast-text-mark”>class=”yoast-text-mark”>class=”yoast-text-mark”>class=”yoast-text-mark”>class=”yoast-text-mark”>class=”yoast-text-mark”>class=”yoast-text-mark”>id=”references”&amp;gt;References</h2&gt;</h2&gt;

<ul><li>=”https://golang.org/pkg/net/http/” rel=”nofollow”>Golang net/http package</a>&lt;/li>