¿Hay alguna manera de descargar un archivo grande usando Go que almacenará el contenido directamente en un archivo en lugar de almacenarlo todo en la memoria antes de escribirlo en un archivo? Debido a que el archivo es tan grande, almacenarlo todo en la memoria antes de escribirlo en un archivo va a agotar toda la memoria.¿Cómo puedo descargar eficientemente un archivo grande usando Go?
Respuesta
Voy a asumir que decir descargar a través de http (comprobaciones de errores omitidos por razones de brevedad):
import ("net/http"; "io"; "os")
...
out, err := os.Create("output.txt")
defer out.Close()
...
resp, err := http.Get("http://example.com/")
defer resp.Body.Close()
...
n, err := io.Copy(out, resp.Body)
Administración de la http.Response es un lector, lo que puede utilizar cualquiera de las funciones que se llevan a un lector, que, p.ej lee un trozo a la vez en lugar de todos a la vez. En este caso específico, io.Copy()
hace el gruntwork por usted.
Aquí hay un ejemplo. https://github.com/thbar/golang-playground/blob/master/download-files.go
También te doy algunos códigos que pueden ayudarte.
código:
func HTTPDownload(uri string) ([]byte, error) {
fmt.Printf("HTTPDownload From: %s.\n", uri)
res, err := http.Get(uri)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
d, err := ioutil.ReadAll(res.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("ReadFile: Size of download: %d\n", len(d))
return d, err
}
func WriteFile(dst string, d []byte) error {
fmt.Printf("WriteFile: Size of download: %d\n", len(d))
err := ioutil.WriteFile(dst, d, 0444)
if err != nil {
log.Fatal(err)
}
return err
}
func DownloadToFile(uri string, dst string) {
fmt.Printf("DownloadToFile From: %s.\n", uri)
if d, err := HTTPDownload(uri); err == nil {
fmt.Printf("downloaded %s.\n", uri)
if WriteFile(dst, d) == nil {
fmt.Printf("saved %s as %s\n", uri, dst)
}
}
}
Este ejemplo lee todo el contenido en la memoria, con 'ioutil.ReadAll()'. Está bien, siempre y cuando se trate de archivos pequeños. – eduncan911
@ eduncan911, pero no está bien para esta pregunta que explícitamente habla de archivos grandes y no quiere absorberlo todo en la memoria. –
Exactamente, por eso lo comenté, para que otros también lo sepan y no lo usen para archivos de gran tamaño. – eduncan911
Una versión más descriptivo de la respuesta de Steve M.
import (
"os"
"net/http"
"io"
)
func downloadFile(filepath string, url string) (err error) {
// Create the file
out, err := os.Create(filepath)
if err != nil {
return err
}
defer out.Close()
// Get the data
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
// Check server response
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("bad status: %s", resp.Status)
}
// Writer the body to file
_, err = io.Copy(out, resp.Body)
if err != nil {
return err
}
return nil
}
La respuesta seleccionada anteriormente utilizando io.Copy
es exactamente lo que necesita, pero si usted está interesado en las características adicionales como la reanudación de descargas interrumpidas, archivos de denominación automática, validación de la suma o monitorear el progreso de las descargas múltiples, pago y envío del paquete grab.
- 1. ¿Cómo escribir eficientemente un archivo de texto grande en C#?
- 2. HTTP Descargar archivo muy grande
- 3. ¿Cómo puedo descargar un archivo XML usando C#?
- 4. Cómo descargar mediante programación un archivo grande en C#
- 5. Analizando eficientemente un archivo de texto grande en C#
- 6. Descargar un archivo usando Javascript
- 7. ¿Cómo puedo descargar dinámicamente un archivo javascript?
- 8. Cómo descargar un archivo grande usando PHP (bajo uso de memoria)
- 9. ¿Cómo puedo descargar un archivo de EC2
- 10. NSURLConnection descargar archivo grande (> 40MB)
- 11. Descargar un archivo usando HTTP en WebDriver
- 12. ¿Cómo descargar un archivo usando curl en php?
- 13. ¿Cómo descargar un archivo de SFTP usando PHP?
- 14. ¿Dónde puedo descargar un archivo ascmd.exe?
- 15. ¿Cómo analizo eficientemente un archivo CSV en Perl?
- 16. (cómo) puedo descargar una imagen usando JSoup?
- 17. ¿descargar archivo zip usando java?
- 18. ¿Cómo puedo transmitir un archivo usando werkzeug?
- 19. Descargar un archivo de Internet usando Java: ¿Cómo autenticar?
- 20. ¿Cómo descargar un archivo usando el cliente GWT?
- 21. Muestra eficientemente una lista grande en HTML
- 22. ¿Cómo puedo usar msbuild para descargar un archivo?
- 23. ¿Cómo puedo compilar un programa Go?
- 24. Descargar archivo usando Java Common Apache?
- 25. Descargar archivo usando libcurl en C/C++
- 26. Descargar un archivo usando curl desde un servidor php
- 27. Descargar el archivo CSV usando "AJAX"
- 28. Importar archivo csv grande usando phpMyAdmin
- 29. cómo descargar un archivo en java?
- 30. ¿Cómo puedo descargar una DLL usando ctypes en Python?
Tenga en cuenta que 'io.Copy' lee 32kb (máximo) desde la entrada y los escribe en la salida, luego se repite. Así que no te preocupes por la memoria. –