Чтение локального файла в Google App Engine с помощью Go - PullRequest
3 голосов
/ 05 августа 2011

Я пытаюсь использовать go вместо python для своего веб-сайта на движке приложений Google. Но я продолжаю получать эту ошибку с моим скриптом, когда я тестирую локально.

panic: runtime error: invalid memory address or nil pointer dereference

Я немного сбит с толку, однако, если я закомментирую, он будет работать без ошибок

channel <- buffer[0:dat]

Значит, я должен использовать каналы неправильно, нужна помощь?

Edit:

Это рабочий код, большое спасибо Кевину Балларду за помощь в получении этого кода.

package defp

import (
    "fmt"
    "http"
    "os"
)

func getContent(filename string, channel chan []byte) {
    file, err := os.OpenFile(filename, os.O_RDONLY, 0666)
    defer file.Close()
    if err == nil {
        fmt.Printf("FILE FOUND : " + filename + " \n")
        buffer := make([]byte, 16)
        dat, err := file.Read(buffer)
        for err == nil {
            fmt.Printf("herp")
            channel <- buffer[0:dat]
            buffer = make([]byte, 16)
            dat, err = file.Read(buffer)
        }
        close(channel)
        fmt.Printf("DONE READING\n")
    } else {
        fmt.Printf("FILE NOT FOUND : " + filename + " \n")
    }
}
func writeContent(w http.ResponseWriter, channel chan []byte) {
    fmt.Printf("ATTEMPTING TO WRITE CONTENT\n")
    go func() {
        for bytes := range channel {
            w.Write(bytes)
            fmt.Printf("BYTES RECEIVED\n")
        }
    }()
    fmt.Printf("FINISHED WRITING\n")
}
func load(w http.ResponseWriter, path string) {
    fmt.Printf("ATTEMPTING LOAD " + path + "\n")
    channel := make(chan []byte, 50)
    writeContent(w, channel)
    getContent(path, channel)
}
func handle(w http.ResponseWriter, r *http.Request) {
    fmt.Printf("HANDLING REQUEST FOR " + r.URL.Path[1:] + "\n")
    load(w, r.URL.Path[1:])
}
func init() {
    http.HandleFunc("/", handle)
}

1 Ответ

5 голосов
/ 28 октября 2011

Причина, по которой ваша программа иногда вызывает панику, заключается в том, что она иногда записывает в w http.ResponseWriter после выхода из функции load. Пакет http автоматически закрывает http.ResponseWriter, когда программа выходит из функции обработчика. В функции writeContent программа иногда пытается выполнить запись в закрытое http.ResponseWriter.

Кстати: вы можете уменьшить исходный код программы, если используете функцию io.Copy.

Чтобы всегда получать предсказуемое поведение, убедитесь, что вся работа , которую программа должна выполнять в ответ на HTTP-запрос , выполняется перед выходом из функции обработчика . Например:

func writeContent(w http.ResponseWriter, channel chan []byte) {
    fmt.Printf("ATTEMPTING TO WRITE CONTENT\n")
    for bytes := range channel {
            w.Write(bytes)
            fmt.Printf("BYTES RECEIVED\n")
    }
    fmt.Printf("FINISHED WRITING\n")
}

func load(w http.ResponseWriter, path string) {
    fmt.Printf("ATTEMPTING LOAD " + path + "\n")
    channel := make(chan []byte)
    workDone := make(chan byte)
    go func() {
            writeContent(w, channel)
            workDone <- 1 //Send an arbitrary value
    }()
    go func() {
            getContent(path, channel)
            workDone <- 2 //Send an arbitrary value
    }()
    <-workDone
    <-workDone
}

func handle(w http.ResponseWriter, r *http.Request) {
    fmt.Printf("HANDLING REQUEST FOR " + r.URL.Path[1:] + "\n")
    load(w, r.URL.Path[1:])
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...