3

Using this answer, with mkdirp, I want to create a directory and save files inside. Inside of plates those folders will be created and reuse if present.

const fs = require('fs')
const mkdirp = require('mkdirp')

// Decode image then save to local storage
const decodeBase64Image = (string, plateNumber) => {
  let regex = /^data:.+\/(.+);base64,(.*)$/
  let matches = string.match(regex)
  let ext = matches[1]
  let data = matches[2]
  let buffer = new Buffer(data, 'base64') // I cant use Buffer.alloc()

  let pathForImages = `plates/${plateNumber}`

  saveImagesToPath(pathForImages, ext, buffer)
}


const saveImagesToPath = (pathForImages, ext, buffer) => {
  mkdirp(pathForImages, function (err) {

    fs.writeFileSync(pathForImages, 'data.' + ext, buffer) 

  })
}

let string = "data:image/gif;base64,R0lGODlhPQBEAPeoAJosM//AwO/AwHVYZ/<SHORTEN>w=="

// Performing it all
decodeBase64Image(string, 'HGT5KU')

Error message:

fs.js:651
  return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);
                 ^

Error: EISDIR: illegal operation on a directory, open 'plates/HGT5KU'

Basically, create a sub-folder for "plates" with the name of the plate numbers and save data inside that folder: plates/HGT5KU/foo.png others: plates/GFTYU7/bar.jpg

Sylar
  • 11,422
  • 25
  • 93
  • 166

2 Answers2

31

You're telling fs.writeFileSync to write to the directory, not to a file within the directory:

mkdirp(pathForImages, function (err) {
  fs.writeFileSync(pathForImages, 'data.' + ext, buffer) 
// ----------------^^^^^^^^^^^^
})

Of course that's going to fail. You need to add a filename to the path:

mkdirp(pathForImages, function (err) {
  const filename = /*...create appropriate filename...*/;
  fs.writeFileSync(pathForImages + "/" + filename, 'data.' + ext, buffer) 
})

Side notes:

  1. It's not generally good practice to ignore errors. mkdirp can fail, you need to check err.

  2. Since mkdirp is asynchronous, using a synchronous call within it is pointless and unnecessarily ties up the JavaScript thread. Just use writeFile. In general, avoid xyzSync functions without a really good reason to use them.

  3. Proabably best to test for errors from writeFileSync/writeFile, too. :-)

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Yes, I remove the `err` for example but it's there. But yes, I now see. Thanks! – Sylar Jun 23 '17 at 11:12
  • I did this way: "fs.writeFile(__dirname + `/../${pathForImages + '/data.' + ext}`, buffer, function(err) { })" Code highlight not great but you understand. Thanks again – Sylar Jun 23 '17 at 11:16
  • @Sylar: No worries. BTW, if you need to put backticks in a code span in a comment, you can use two backticks around the span to quote it rather than just one: ``fs.writeFile(__dirname + `/../${pathForImages + '/data.' + ext}`, buffer, function(err) { })`` That's backtick backtick code backtick backtick. – T.J. Crowder Jun 23 '17 at 11:26
1

Please use the file name in the path along with the file data.

Ex:

const fullPath = path.join('c/d', 'somefilename');
fs.writeFile(fullPath, file.data);
Dharman
  • 30,962
  • 25
  • 85
  • 135
Yoga
  • 491
  • 5
  • 8