Node fs showing that file is not directory when it is - node.js

I have the following code...
console.log("looking for "+ path+" "+fs.lstatSync(path).isDirectory());
with path == "/Volumes/Macintosh HD" I get
looking for /Volumes/Macintosh HD false
I also tried converting to "/Volumes/Macintosh\ HD" but then it can't even find the file.
Why is this not showing up as a directory?

This is because /Volumes/Macintosh HD is actually a symlink to /. It's not actually a directory.
You can do this instead:
console.log("looking for "+ path+" symlink: "+fs.lstatSync(path).isSymbolicLink());
// outputs: looking for /Volumes/Macintosh HD symlink: true
If you wanted to integrate this in your logic to check to see if the symlink is pointing to a directory, you can try something like this:
var path = '/Volumes/Macintosh HD';
if (fs.lstatSync(path).isSymbolicLink()) {
// replace 'path' with the real path if it's a symlink
path = fs.readlinkSync(path);
}
if (fs.lstatSync(path).isDirectory()) {
console.log('it is a directory!');
}

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']);

How to access /tmp folder in Lambda with in Node?

I'm trying to save a processed image momentally in /tmp folder but it's not working for me. Assuming it's under the root folder I'm trying to get it this way:
let tempraryImageDirectory: string;
if (process.env.DEV && process.env.DEV === 'Yes') {
tempraryImageDirectory = path.join(__dirname, `../../tmp/`);
} else {
tempraryImageDirectory = path.join(__dirname, `./tmp/`);
}
The else choice here is to test locally. I don't want to create a /tmp folder in the root directory. Locally everything is very fine. But in Lambda at the moment any operation happens on the directory CloudWatch never shows any of my logs written after that and my function fails for unknown reason.
Any idea if I'm addressing the /tmp folder correctly?
The directory is just /tmp, it is not relative to the working directory:
let tempraryImageDirectory: string;
if (process.env.DEV && process.env.DEV === 'Yes') {
tempraryImageDirectory = path.join(__dirname, `../../tmp/`);
} else {
tempraryImageDirectory = '/tmp/';
}
You may also wish to rename your variable to include the o in temporary if you did not leave it out on purpose.
Change this: ./tmp/, i.e. "the /tmp directory under the current working directory"
To this: /tmp/, i.e. "the /tmp directory under the root file system"

Switch to what ever path is input nodejs

Lets assume you have installed an electron app and you are asked to input the path to your current project. You might do something like: ~/Documents/projectName.
How do I, in node take that input and check if it exists, specifically if you entered in the path as shown above?
the reason for this is that I want to see if A) the path exists and B) if theres a specific file there (I'll be using path.join(dirEntered, fileName.extension).
Is there a way to do what I want? I see chdir but that changes where the working directory is. which I guess would be fine but doing:
process.chdir('~/Documents') Shows: no such file or directory, uv_chdir(…)
I want to avoid having the user to enter the full absolute path of their project. That seems "bad to me". And uploading their project isn't necessary, Im reading a single file (so theres no need for upload here).
Any ideas?
Is it possible to tap into the cli commands and take this input feed it there and get the result? Or is that over kill?
Here's an idea how to solve it. If the path starts with a tilde, it replaces that tilde with the full home directory of the current user. It then uses fs.stat to see if the given path actually exists.
const fs = require("fs");
const os = require("os");
var path = "~/Documents";
if (path.indexOf("~") === 0) {
path = os.homedir() + path.substring(1);
}
fs.stat(path, (err, stats) => {
if (!err) {
// document or path exists
if (stats.isFile()) {
console.log("Path " + path + " is a file");
} else if (stats.isDirectory()) {
console.log("Path " + path + " is a directory");
}
} else {
// document or path does not exist
}
});

NodeJS - error EPERM when moving file to its parent directory?

I found this answer saying to use mv module.
But it doesn't seem it works if I want to move file to its parent directory.
For example I want to move all files on /tmp to /
var root = process.cwd(); // the directory where i run the script
mv(root + "/tmp", root, { mkdirp: true }, function(err) {
if(err) { return logger.error(err); }
});
and I got this error:
error: Error: EPERM, rename 'C:\Users\myusername\Documents\test\tmp'
I think it's because moving in NodeJS uses rename workaround and it can't rename it to the parent directory.
Any solution? Thanks
Nevermind, used fs-extra module here.
the fs.move actually works

Node.js fs.unlink function causes EPERM error

I'm using fs.unlink() to delete a file and I receive the following error:
uncaught undefined:
Error: EPERM, Operation not permitted '/Path/To/File'
Anyone know a why this is happening?
You cannot delete a directory that is not empty.
And fs.unlinkSync() is used to delete a file not a folder.
To remove an empty folder, use
fs.rmdir()
to delete a non empty folder, use this snippet:
var deleteFolderRecursive = function(path) {
if( fs.existsSync(path) ) {
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);
}
};
Snippet from stackoverflow: Is node.js rmdir recursive ? Will it work on non empty directories?
If you want to achieve something like rm -rf does, there is a package from npm called rimraf which makes it very easy.
Maybe the Path of the file is located is erroneus.
if not, try with fs.unlinkSync()
Yes, you don't have permission to delete/unlink that file. Try again with more rights or verify that you're giving it the right path.

Resources