# Inviare file e stream al client

> Servi un file dal disco con $.file(), imponi un nome di download, trasmetti contenuto generato con $.stream() e rispondi 404 quando il file manca.

Framework: total5
Product: Total.js 5 (total5@0.0.19)
Language: it
Content-SHA256: 5f466e3c421bb3e975e2eaf462cbdf881562b8335037ba9ac4700f685362f9ed
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: total5-installed@total5@0.0.19
Review: not-recorded

`$.file(path, [download])` invia un file dal disco. Il `content-type` deriva dall'estensione. Passa `true` come secondo argomento perché il browser scarichi il file con il suo nome, oppure una stringa per scegliere il nome (`attachment; filename*=...` viene impostato per te, sicuro con UTF-8). Un percorso che non esiste termina con la pagina 404.

`$.stream(type, stream, [download])` invia qualsiasi stream leggibile con il content type indicato: un file generato, la risposta di un altro server o un'esportazione di database. Non imposta la lunghezza, quindi la risposta viene inviata a blocchi. `PATH.public()`, `PATH.private()` e `PATH.tmp()` costruiscono percorsi assoluti verso le cartelle del progetto; i file in `public/` sono già serviti senza alcuna rotta, quindi usa `$.file()` per i file che devono restare privati o richiedono prima un controllo.

```js controllers/download.js
const Fs = require('fs');

exports.install = function() {
	ROUTE('GET /report/', report);
	ROUTE('GET /report/save/', report_save);
	ROUTE('GET /export/', export_csv);
	ROUTE('GET /missing/', missing);
};

function filepath() {
	var filename = PATH.tmp('report.txt');
	Fs.writeFileSync(filename, 'Total.js report\n');
	return filename;
}

function report($) {
	$.file(filepath());
}

function report_save($) {
	$.file(filepath(), 'my report.txt');
}

function export_csv($) {
	var stream = Fs.createReadStream(filepath());
	$.stream('text/csv', stream, 'export.csv');
}

function missing($) {
	$.file(PATH.tmp('does-not-exist.txt'));
}
```
