1
votes

I am trying to delete the file object that is created and stored in the uploads folder.

Here is my config options for multer:

const path = require('path')

multerConfigOpt = {
    dest: 'uploads/',
    fileFilter:  function(req, file, cb) {
        var ext = path.extname(file.originalname)
        console.log(ext);
        if (ext === '.pdf' || ext === '.doc' || ext === '.docx' || ext === '.txt') {
            console.log("true!");
            cb(null,true)
        } else {
            cb(null, false)
        }
    }
}

module.exports = multerConfigOpt

After processing the files that was submitted by a user via a HTML Form I would like to delete it. When I try and do the following:

    await fs.unlink(this.file.path, (err) => {
        if (err) {
            console.log(err);
        }
    })

However I get the following error:

Error: EPERM: operation not permitted,

these files that are store in the uploads folder do not have an extension. I believe they are just binary files that were created by multer.

Below is an example of the file that is in the uploads folder path.

enter image description here

All I do with the file is send it as an attachment through email using nodemailer

if (this.file && this.isJobSeeker) {
    mailOptions.attachments = [{
        filename: 'resume.pdf',
        content:  fs.createReadStream(this.file.path)
    }]
}

How can I delete these files?

Thank you for the help.

1
Does "processing" your file invoive reading the files into memory?Anuj Pancholi
@AnujPancholi I've updated my previous question to show how i handle the processingNick
Can you check what this.file.path is? Seems like folder rather than file. And hence the EPERM error. Or fs.unlink couldn't find this file.ambianBeing
I think you could find solution on this link stackoverflow.com/a/63895045/12761193Arya

1 Answers

1
votes

The createReadStream function in fs also may take a buffer as an input, however, it seems that fs.createReadStream() converts that buffer to a string which ultimately must contain a file path (which seems like an important detail they should've mentioned in the docs).

Multer has a feature where instead of storing the file on your disk, you can have the file as an in-memory buffer.

You may try:

const multerMemoryStorage = multer.memoryStorage();

multerConfigOpt = {
    storage: multerMemoryStorage,
    fileFilter:  function(req, file, cb) {
        var ext = path.extname(file.originalname)
        console.log(ext);
        if (ext === '.pdf' || ext === '.doc' || ext === '.docx' || ext === '.txt') {
            console.log("true!");
            cb(null,true)
        } else {
            cb(null, false)
        }
    }
}

Then, if you're taking req.file in this.file in your processing function, you can do the following:

Using the stream module in nodejs, we can convert the buffer into a readable stream, which is the base class of fs.ReadStream.

const stream = require('stream')
const getNewReadableStreamFromBuffer = (inputBuffer) => {
    const readable = new stream.Readable.from(inputBuffer);
    

    return readable;
}
if (this.file && this.isJobSeeker) {
    mailOptions.attachments = [{
        filename: 'resume.pdf',
        content: getNewReadableStreamFromBuffer(this.file.buffer)
    }]
}

The file need not be deleted, because it's never saved to disk. And since nodejs is garbage collected, the buffer should be cleared from memory.

NOTE: Multer docs mention in a warning that in this approach, you must ensure that your server has enough memory to keep in-memory buffers of uploaded files, as some files may be quite large. If your files are small enough, it will work smoothly.