Ответ 1
Я постараюсь ответить на ваш вопрос реальным примером жизни, по крайней мере, вы могли бы изучить некоторые вещи из него. Если вы хотите удалить все, кроме самой последней загрузки, тогда вам нужно закодировать какую-то логику, чтобы различать, какой из последних загрузок и какие старые. Ниже я описываю, как бы я решил решить эту проблему, может быть, не идеально, но вот как я это делаю.
Папка никогда не будет удаляться автоматически, если вы не удалите ее вручную или программно.
Размер папки с 100 вызовами, предполагая, что в каждом вызове вы загружаете файл размером x, будет x умножен на 100
Вы не хотите ограничивать загрузку файлов, не предоставляете лимиты, но рекомендуется указывать ограничение на загрузку файлов.
Очевидно, вы можете приложить к нему приложение multer или создать его экземпляр и передать его маршруту. Я предпочитаю второй метод:
Конфигурация multer
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/')
},
filename: function (req, file, cb) {
var filename = file.originalname;
var fileExtension = filename.split(".")[1];
cb(null, Date.now() + "." + fileExtension);
}
});
Как показано выше, я не позволяю мультеру давать случайное имя загруженному файлу. То, что я делаю, это получить имя файла, отменить его расширение, а затем использовать Date.now()
, который даст мне текущую временную метку, добавленную с расширением загруженного файла. Если я сделаю шесть загрузок, они будут отображаться следующим образом (большинство моих загрузок были .jpg, которые взяты из имени файла).
Как будет загружаться (временные метки будут отличаться)
1453414099665.jpg (oldest)
1453414746114.JPG
1453414748991.jpg
1453414751662.jpg
1453414754815.jpg (most recent)
Я приложил вышеуказанный storage
к экземпляру multer, как показано ниже:
var upload = multer({storage: storage});
Теперь я могу передать upload
на маршрут, который обрабатывает загрузку файла следующим образом:
добавить загрузку на маршрут, как показано ниже
//simple route to return upload form, simple jade file
app.get('/upload', function(req, res){
res.render('upload');
});
//this route processes the upload request, see below upload.single('file')
//is the passed multer
app.post('/upload', upload.single('file'), function(req,res){
res.status(204).end();
});
Скажем, вы продолжаете загружать, а затем в какой-то момент вы хотите перечислить все файлы в каталоге uploads. Маршрут будет следующим:
Список всех файлов в каталоге загрузок
//lists all files in the uploads directory and return it to browser as json response
app.get('/listAllFiles', function(req, res) {
//reading directory in synchronous way
var files = fs.readdirSync('./uploads');
res.json(files);
});
Вы хотите удалить все файлы в каталоге загрузки, маршрут будет выглядеть следующим образом:
Удалить все файлы в каталоге загрузок
//delete all files in the upload direcotry asynchronously
app.get('/deleteAllFiles', function(req, res) {
fs.readdir('./uploads', function(err, items) {
items.forEach(function(file) {
fs.unlink('./uploads/' + file);
console.log('Deleted ' + file);
});
res.status(204).end();
});
});
Если вы хотите удалить все файлы синхронно, вы должны вызвать версию синхронизации readdir (readdirSync) и unlink (unlinkSync)
var filenames = fs.readdirSync('./uploads');
filenames.forEach(function(file) {
fs.unlinkSync('./uploads/' + file);
});
Теперь вам нужно удалить все, кроме самого последнего загруженного файла. Ну, я уже сделал все имена файлов timestamps. Поэтому я бы сделал что-то следующее:
Удалите все файлы, кроме последних (где последнее из них является самым последним в качестве имени файла).
//delets all file asynchronously except the most recent in which case the file
//with name being the latest timestamp is skipped.
app.get('/deleteAllExceptMostRecent', function(req, res) {
console.log('/deleteAllFilesExceptMostRecent');
fs.readdir('./uploads', function(err, items) {
//sort the array of files names in reverse, so we have most recent file on top
items.reverse();
var flag = true;
items.forEach(function(file) {
//skip deletion of most recent file. if condition executed onces only.
if(flag) {
flag = false;
} else {
fs.unlink('./uploads/' + file);
console.log('Deleted ' + file);
}
});
});
res.status(204).end();
});
Я не добавил никаких ограничений в свой пример, но рекомендуется. Предел размера файла по умолчанию - бесконечность, и если вы не включаете его в среду prod, вы будете уязвимы для DoS-атак, как указано в комментариях.
Для работы вышеприведенного файла вам нужно загрузить
var fs = require('fs');
Что касается вашей второй точки, просто пропустите свойство limits, а предел по умолчанию будет бесконечным.
В демонстрационных целях я установил это в рабочем приложении nodejs, см. ниже:
app.js
var express = require('express');
var multer = require('multer');
var bodyParser = require('body-parser');
var path = require('path');
var fs = require('fs');
var app = new express();
app.use(bodyParser.json());
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/')
},
filename: function (req, file, cb) {
/* if you need to retain the original filename, then use filename and append to it date
* if you don't need original filename but, just extension, then append extension at the
* end of current timestamp. If you don't need extenion then just use Date.now() which
*/
var filename = file.originalname;
var fileExtension = filename.split(".")[1];
cb(null, Date.now() + "." + fileExtension);
}
})
var upload = multer({storage: storage});
//get upload form
app.get('/upload', function(req, res){
res.render('upload');
});
//process upload
app.post('/upload', upload.single('file'), function(req,res){
res.status(204).end();
});
//lists all files in the uploads directory.
app.get('/listAllFiles', function(req, res) {
var files = fs.readdirSync('./uploads');
res.json(files);
});
//delete all files in the upload direcotry asynchronously
app.get('/deleteAllFiles', function(req, res) {
fs.readdir('./uploads', function(err, items) {
items.forEach(function(file) {
fs.unlink('./uploads/' + file);
console.log('Deleted ' + file);
});
res.status(204).end();
});
});
//delets all file asynchronously except the most recent in which case the file
//with name being the latest timestamp is skipped.
app.get('/deleteAllExceptMostRecent', function(req, res) {
console.log('/deleteAllFilesExceptMostRecent');
fs.readdir('./uploads', function(err, items) {
items.reverse();
var flag = true;
items.forEach(function(file) {
if(flag) {
flag = false;
} else {
fs.unlink('./uploads/' + file);
console.log('Deleted ' + file);
}
});
});
res.status(204).end();
});
//delete all files of a direcotry in synchronous way
app.get('/deleteAllSync', function(req, res) {
var filenames = fs.readdirSync('./uploads');
filenames.forEach(function(file) {
fs.unlinkSync('./uploads/' + file);
});
});
//delete all files except most recent in synchronous way
app.get('/deleteAllSyncExceptMostRecent', function(req, res) {
var filenames = fs.readdirSync('./uploads');
filenames.reverse();
var flag = true;
filenames.forEach(function(file) {
if(flag)
flag = false;
else
fs.unlinkSync('./uploads/' + file);
});
});
var port = 3000;
app.listen( port, function(){ console.log('listening on port '+port); } );
вид /upload.jade
html
head
title
body
form(method="post",enctype="multipart/form-data",action="/upload")
p
input(type="file",name="file")
p
input(type="submit")