読者です 読者をやめる 読者になる 読者になる

Revel でファイルアップロード

ビュー側で下記のような感じで書く.

<form action="/upload" enctype="multipart/form-data" method="post">
    <input type="file" name="uploadFile" />
    <input type="submit" />
</form>

コントローラで下記のような感じで書く.ファイルを保存する部分は ioutil.ReadAll() でもいいけどアップロードするファイルサイズが大きければ確保すべきメモリもでかくなってくるので,メモリをあんまり食いつぶしたくなければ下記のように少しずつやるのがよさそう.ちなみに ReadByte(), WriteByte() もやってみたけど CPU 使いすぎ. os.Rename() も試したけど実際に保存されている場所を取得することがぱっと見できなさそうなのでだめだった.

func (c App) Upload() revel.Result {
        for _, fileHeaders := range c.Params.Files {
                for _, fileHeader := range fileHeaders {
                        path := "files/" + fileHeader.Filename
                        outFile, err := os.Create(path)
                        if err != nil {
                                log.Println(err)
                        }   
                        writer := bufio.NewWriter(outFile)

                        file, _ := fileHeader.Open()
                        reader := bufio.NewReader(file)
                        bufsize := 4 * 1024 * 1024
                        buf := make([]byte, bufsize)
                        for {
                                n, err := reader.Read(buf)
                                if err != nil {
                                        break
                                }   
                                _, err = writer.Write(buf[:n])
                                if err != nil {
                                        log.Println(err)
                                        break
                                }   
                        }   
                        writer.Flush()
                }   
        }   

        return c.Render()
}

tmpFiles にファイルパスあるっぽいけどこれつかって Rename() できたらパフォーマンス良くなりそうなんだけどどうなんだろう.グローバルじゃないのでアクセス出来ないけど.

params.go
 28         Files    map[string][]*multipart.FileHeader // Files uploaded in a multipart form
 29         tmpFiles []*os.File                         // Temp files used during the request.
 30 }