48 lines
2.0 KiB
Markdown
48 lines
2.0 KiB
Markdown
---
|
|
name: file_save_disk
|
|
kind: function
|
|
lang: go
|
|
domain: infra
|
|
version: "1.0.0"
|
|
purity: impure
|
|
signature: "func FileSaveDisk(baseDir string, filename string, data io.Reader) (UploadedFile, error)"
|
|
description: "Escribe el contenido de un io.Reader a disco en baseDir con un nombre unico (UUID + extension). Crea el directorio si no existe. Retorna UploadedFile con metadata."
|
|
tags: [file, save, disk, storage, upload, infra]
|
|
uses_functions: [file_unique_name_go_infra]
|
|
uses_types: [UploadedFile_go_infra]
|
|
returns: [UploadedFile_go_infra]
|
|
returns_optional: false
|
|
error_type: "error_go_core"
|
|
imports: [fmt, io, mime, os, path/filepath, strings, time]
|
|
params:
|
|
- name: baseDir
|
|
desc: "directorio destino (se crea si no existe, permisos 0755)"
|
|
- name: filename
|
|
desc: "nombre original del archivo (solo se usa para extraer la extension)"
|
|
- name: data
|
|
desc: "reader con el contenido binario a escribir"
|
|
output: "UploadedFile con StoredName (UUID-based), Path completo, Size en bytes, ContentType inferido por extension y CreatedAt (UTC). Error si falla mkdir, create o copy"
|
|
tested: true
|
|
tests: ["guarda contenido en baseDir con nombre UUID", "crea baseDir si no existe", "tamano coincide con bytes escritos", "infiere ContentType desde la extension"]
|
|
test_file_path: "functions/infra/file_save_disk_test.go"
|
|
file_path: "functions/infra/file_save_disk.go"
|
|
---
|
|
|
|
## Ejemplo
|
|
|
|
```go
|
|
f, _ := os.Open("./input.png")
|
|
defer f.Close()
|
|
uploaded, err := FileSaveDisk("./uploads", "input.png", f)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
fmt.Println(uploaded.Path) // ./uploads/{uuid}.png
|
|
```
|
|
|
|
## Notas
|
|
|
|
- El nombre original NUNCA se usa como nombre en disco (riesgo path traversal). Solo se preserva como metadata en el campo `Filename` para trazabilidad.
|
|
- ContentType se infiere de la extension via `mime.TypeByExtension`. Para validacion estricta del tipo real, llamar `FileValidateType` ANTES de guardar y/o sobreescribir el campo.
|
|
- Si falla el `io.Copy`, el archivo parcial se borra automaticamente.
|