File and folders create if not exist - node.js

Is there anything like fs.create(path) that if path not exist then create it.
For example, fs.Create('D:/test/a.txt') and it will create test folder and a.txt file if a.txt not exist.
I know how to create the file if not exist but how about folder's'?
I think it is a simple problem. Does any lib can do that? Or I need to parse the path and create it?

If you don't want to add dependencies the following may work for you, where dirPath is an array of the path segments you want to mkdirsync to:
let dirPath = [cwd, `..`, `..`, `folderA`, `folderB`]
let outDir = []
dirPath.forEach(element => {
outDir.push(element)
try {
if (!fs.existsSync(path.resolve(outDir.join('/')))) {
fs.mkdirSync(path.resolve(outDir.join('/')))
console.log('mkdir succeeded!!')
}
} catch (err) {
console.error(err)
}
})

The answer is from #thefourtheye, Use fs-extra module's mkdirs

Related

How to delete all files and subdirectories in a directory with Node.js

I am working with node.js and need to empty a folder. I read a lot of deleting files or folders. But I didn't find answers, how to delete all files AND folders in my folder Test, without deleting my folder Test` itself.
I try to find a solution with fs or extra-fs. Happy for some help!
EDIT 1: Hey #Harald, you should use the del library that #ziishaned posted above. Because it's much more clean and scalable. And use my answer to learn how it works under the hood :)
EDIT: 2 (Dec 26 2021): I didn't know that there is a fs method named fs.rm that you can use to accomplish the task with just one line of code.
fs.rm(path_to_delete, { recursive: true }, callback)
// or use the synchronous version
fs.rmSync(path_to_delete, { recursive: true })
The above code is analogous to the linux shell command: rm -r path_to_delete.
We use fs.unlink and fs.rmdir to remove files and empty directories respectively. To check if a path represents a directory we can use fs.stat().
So we've to list all the contents in your test directory and remove them one by one.
By the way, I'll be using the synchronous version of fs methods mentioned above (e.g., fs.readdirSync instead of fs.readdir) to make my code simple. But if you're writing a production application then you should use asynchronous version of all the fs methods. I leave it up to you to read the docs here Node.js v14.18.1 File System documentation.
const fs = require("fs");
const path = require("path");
const DIR_TO_CLEAR = "./trash";
emptyDir(DIR_TO_CLEAR);
function emptyDir(dirPath) {
const dirContents = fs.readdirSync(dirPath); // List dir content
for (const fileOrDirPath of dirContents) {
try {
// Get Full path
const fullPath = path.join(dirPath, fileOrDirPath);
const stat = fs.statSync(fullPath);
if (stat.isDirectory()) {
// It's a sub directory
if (fs.readdirSync(fullPath).length) emptyDir(fullPath);
// If the dir is not empty then remove it's contents too(recursively)
fs.rmdirSync(fullPath);
} else fs.unlinkSync(fullPath); // It's a file
} catch (ex) {
console.error(ex.message);
}
}
}
Feel free to ask me if you don't understand anything in the code above :)
You can use del package to delete files and folder within a directory recursively without deleting the parent directory:
Install the required dependency:
npm install del
Use below code to delete subdirectories or files within Test directory without deleting Test directory itself:
const del = require("del");
del.sync(['Test/**', '!Test']);

Finding files from Windows Volume GUID Name Paths in Node.js

I have several paths in format "\?\Volume{56D4B0E2-0000-0000-0000-00A861000000}\dir1" and I need to find and read JSON files from the paths.
glob doesn't seem to find anything from those paths.
glob(rootDir + '\\**\\*.json', {}, (err, files) => {
...
});
Am I doing something wrong or does glob not support "\?\Volume{}" paths?
Thank you in advance!
I decided to use node fs and path instead of glob:
static getFilesFromPath(path, extension) {
let dir = fs.readdirSync( path );
return dir.filter( elm => elm.match(new RegExp(`.*\.(${extension})`, 'ig')));
}

Node FS not finding folder

Using Node, I create a folder and then have a file in that folder. I created a function to delete it, but it absolutely refuses to find the folder.
Here's my function:
function deleteFile(path) {
if( !fs.existsSync(path) ) {
setTimeout(deleteFile(path), 500)
} else {
fs.readdirSync(path).forEach(function(file){
var curPath = path + "/" + file;
if(fs.lstatSync(curPath).isDirectory()) { // recurse
deleteFolderRecursive(curPath);
} else { // delete file
fs.unlinkSync(curPath);
}
});
fs.rmdirSync(path);
}
}
It will continue to recurse until it hits maximum call stack and crash, but the folder exists LONG before that happens. As you can see, there exists both the folder and the file inside of it. Could someone please help me fix this?
If anyone else comes across this issue, I figured it out. When the folder is created, it gives the incorrect permissions. I used fs.chmod to change permissions beforehand, and that fixed it.

check the type of files is present or not using nodejs

I want to find the type of files which is present or not, I am using nodejs, fs. Here is my code
var location = '**/*.js';
log(fs.statSync(location).isFile());
which always returns the error.
Error: ENOENT, no such file or directory '**/*.js'
How to I find the files is present or not. Thanks in Advance.
node doesn't have support for globbing (**/*.js) built-in. You'll need to either recursively walk the directories and iterate over the array of file names to find the file types you want, or use something like node-glob.
Using recusrive-readdir-sync
var recursiveReadSync = require('recursive-readdir-sync'),
files;
files = recursiveReadSync('./');
files.forEach(function (fileName) {
if (fileName.search(/\.js$/g) !== -1) {
console.log("Found a *.js file");
}
});
Using node-glob:
var glob = require("glob")
glob("**/*.js", function (er, files) {
files.forEach(function (fileName) {
if (fileName.search(/\.js$/g) !== -1) {
console.log("Found a *.js file");
}
});
node.js dose not support "glob" wildcards by default. You can use external package like this one

writeFile no such file or directory

I have a file(data.file an image), I would like to save this image. Now an image with the same name could exist before it. I would like to overwrite if so or create it if it does not exist since before. I read that the flag "w" should do this.
Code:
fs.writeFile('/avatar/myFile.png', data.file, {
flag: "w"
}, function(err) {
if (err) {
return console.log(err);
}
console.log("The file was saved!");
});
Error:
[Error: ENOENT: no such file or directory, open '/avatar/myFile.png']
errno: -2,
code: 'ENOENT',
syscall: 'open',
path: '/avatar/myFile.png'
This is probably because you are trying to write to root of file system instead of your app directory '/avatar/myFile.png' -> __dirname + '/avatar/myFile.png' should do the trick, also check if folder exists. node.js won't create parent folder for you.
Many of us are getting this error because parent path does not exist. E.g. you have /tmp directory available but there is no folder "foo" and you are writing to /tmp/foo/bar.txt.
To solve this, you can use mkdirp - adapted from How to write file if parent folder doesn't exist?
Option A) Using Callbacks
const mkdirp = require('mkdirp');
const fs = require('fs');
const getDirName = require('path').dirname;
function writeFile(path, contents, cb) {
mkdirp(getDirName(path), function (err) {
if (err) return cb(err);
fs.writeFile(path, contents, cb);
});
}
Option B) Using Async/Await
Or if you have an environment where you can use async/await:
const mkdirp = require('mkdirp');
const fs = require('fs');
const writeFile = async (path, content) => {
await mkdirp(path);
fs.writeFileSync(path, content);
}
I solved a similar problem where I was trying to create a file with a name that contained characters that are not allowed. Watch out for that as well because it gives the same error message.
I ran into this error when creating some nested folders asynchronously right before creating the files. The destination folders wouldn't always be created before promises to write the files started. I solved this by using mkdirSync instead of 'mkdir' in order to create the folders synchronously.
try {
fs.mkdirSync(DestinationFolder, { recursive: true } );
} catch (e) {
console.log('Cannot create folder ', e);
}
fs.writeFile(path.join(DestinationFolder, fileName), 'File Content Here', (err) => {
if (err) throw err;
});
Actually, the error message for the file names that are not allowed in Linux/ Unix system comes up with the same error which is extremely confusing. Please check the file name if it has any of the reserved characters. These are the reserved /, >, <, |, :, & characters for Linux / Unix system. For a good read follow this link.
It tells you that the avatar folder does not exist.
Before writing a file into this folder, you need to check that a directory called "avatar" exists and if it doesn't, create it:
if (!fs.existsSync('/avatar')) {
fs.mkdirSync('/avatar', { recursive: true});
}
you can use './' as a prefix for your path.
in your example, you will write:
fs.writeFile('./avatar/myFile.png', data.file, (err) => {
if (err) {
return console.log(err);
}
console.log("The file was saved!");
});
I had this error because I tried to run:
fs.writeFile(file)
fs.unlink(file)
...lots of code... probably not async issue...
fs.writeFile(file)
in the same script. The exception occurred on the second writeFile call. Removing the first two calls solved the problem.
In my case, I use async fs.mkdir() and then, without waiting for this task to complete, I tried to create a file fs.writeFile()...
As SergeS mentioned, using / attempts to write in your system root folder, but instead of using __dirname, which points to the path of the file where writeFile is invoked, you can use process.cwd() to point to the project's directory. Example:
writeFile(`${process.cwd()}/pictures/myFile.png`, data, (err) => {...});
If you want to avoid string concatenations/interpolations, you may also use path.join(process.cwd(), 'pictures', 'myFile.png') (more details, including directory creation, in this digitalocean article).

Resources