How to read from a specified file which is in a folder below without knowing the absolute path - node.js

So I have my project directory:
Here I read ArticleFile:
function _getDataFromFile() {
var jsonArray = csvjson.toObject(fs.readFileSync('ArticleFile.csv', { encoding: 'utf8' }));
var result = [];
for (var idx = 0; idx < jsonArray.length; idx++) {
var currArt = jsonArray[idx];
// if (!checkIfElementIsArticle(currArt)) throw "loaded object IS NOT an article!";
result.push(new Article(currArt.imageLocation, currArt.title, currArt.description, parseInt(currArt.quantity),parseInt(currArt.price)));
}
return result;
}
The problem is if "ArticleFile.csv" is in lets say contentsKopie I have to know the absolute path such as : C:\Users\noone_000\Desktop\BSD\Hausübungen\WebServer\WebServer\contentsKopie\ArticleFile.csv . How can I set the path like: fs.readFileSync('/ContentsCopie/ArticleFile.csv', { encoding: 'utf8' })
PS: csvjson is a module (require("csvjson"))

When you start the path with / it is interpreted as an absolute path. If you want to open a file in sub directory, you can use ./ContentsCopie/ArticleFile.csv
The . in front of the slash means that the path is relative to the current directory.
Conversely, if you needed to go up a level you can prefix your path with ..

Isn't ./contentsKopie/ArticleFile.csv enough?
When using /contentsKopie/ArticleFile.csv it's actually looking in C:/contentsKopie/ArticleFile.csv. So you have to prepend your path with a . to tell it to start at the working directory (WebServer here).
Otherwise, you can have the absolute path of the current file with __dirname then you could compose your path using the path module from node.
var path = require('path');
var article = path.join(__dirname, './contentsKopie/ArticleFile.csv');
This way, you'll get the absolute path of your file.

Related

readdirSync cannot read encrypted home folder when accessing it directly

const fs = require("fs")
//const HOW = "/home/test/everything"
// const HOW = "/home/test/"
// This one fails. My home is encrypted and it cannot read directories, it gets the .Private file. I want to read files and directories in my home folder. But can't.
const HOW = "/home/test/folder/"
// This one works for some reason. It lists all the directories in the folder.
// const HOW = "folder"
// This one works as well
var list = walk(HOW)
console.log(list)
// How do I get contents of /home/test (which happens to be my home folder).
// I'm both root and "test" user of the computer.
I'd like to have walk() work on /home/test/.
The code that fails:
var walk = function(dir) {
var results = []
var list = fs.readdirSync(dir)
list.forEach(function(file) {
file = dir + '/' + file
var stat = fs.statSync(file)
if (stat && stat.isDirectory()) results = results.concat(walk(file))
else results.push(file)
})
return results
}
The exact line causing it (stack trace): var stat = fs.statSync(file)
The error is:
Error: ENOENT: no such file or directory, stat '/home/test/.Private/###############################################################'
Where # is an amount of letters whose importance to safety is unknown to me.
Node.js doesn't have a problem addressing any folder contained within my home folder, but cannot address the home folder itself. Neither my own account nor root account can get access to it.
I think you are adding an unnecessary /. Try changing
const HOW = "/home/test/folder/"
to
const HOW = "/home/test/folder"

Nodejs get absolute path relative to process.cwd()

So I have the following code block:
#!/usr/bin/env node
const path = require('path');
const yargs = require('yargs').argv;
const ghpages = require('gh-pages');
const randomstring = require("randomstring");
const dirName = randomstring.generate({
length: 12,
charset: 'alphabetic'
});
console.log(__dirname, dirName, process.cwd(), yargs.directory, yargs.branch);
ghpages.publish(path.join(process.cwd(), yargs.directory), {
branch: yargs.branch,
clone: `../../../../tmp/${dirName}`
}, () => {
console.log('removing');
});
This requires an absolute path to the clone location.
Obviously I have hard coded it at the moment for testing but what I want to do is get the absolute path to /tmp/ from the process.cwd().
So basically what I want is if I ran the script in /home/otis ../../../../tmp/${dirName} would become ../../tmp/${dirName} so I need to generate the path based on the process.cwd()
Any ideas?
Cheers/
You can use path.resolve to get the absolute path.
e.g.
path.resolve('../src/tmp')
// '/Users/yourusername/src/tmp'
Or you can use the path.relative( from, to ) which gives the relative path between from and to
So in your case, I guess it is
path.relative( process.cwd(), "../../../../tmp/" )
It's bad practice to use relative paths, especially to system folders. In case if a project location will be changed, you will have to update your code as well.
If you need the system temp directory, you can use the following:
require('os').tmpdir()
It will return you correct absolute path to your temporary folder depending on current OS.

Nodejs absolute paths in windows with forward slash

Can I have absolute paths with forward slashes in windows in nodejs? I am using something like this :
global.__base = __dirname + '/';
var Article = require(__base + 'app/models/article');
But on windows the build is failing as it is requiring something like C:\Something\Something/apps/models/article. I aam using webpack. So how to circumvent this issue so that the requiring remains the same i.e. __base + 'app/models/src'?
I know it is a bit late to answer but I think my answer will help some visitors.
In Node.js you can easily get your current running file name and its directory by just using __filename and __dirname variables respectively.
In order to correct the forward and back slash accordingly to your system you can use path module of Node.js
var path = require('path');
Like here is a messed path and I want it to be correct if I want to use it on my server. Here the path module do everything for you
var randomPath = "desktop//my folder/\myfile.txt";
var correctedPath = path.normalize(randomPath); //that's that
console.log(correctedPath);
desktop/my folder/myfile.txt
If you want the absolute path of a file then you can also use resolve function of path module
var somePath = "./img.jpg";
var resolvedPath = path.resolve(somePath);
console.log(resolvedPath);
/Users/vikasbansal/Desktop/temp/img.jpg
it's 2020, 5 years from the question was published, but I hope that for somebody my answer will be useful. I've used the replace method, here is my code(express js project):
const viewPath = (path.join(__dirname, '../views/')).replace(/\\/g, '/')
exports.articlesList = function(req, res) {
res.sendFile(viewPath + 'articlesList.html');
}
I finally did it like this:
var slash = require('slash');
var dirname = __dirname;
if (process.platform === 'win32') dirname = slash(dirname);
global.__base = dirname + '/';
And then to require var Article = require(__base + 'app/models/article');. This uses the npm package slash (which replaces backslashes by slashes in paths and handles some more cases)
The accepted answer doesn't actually answer the question most people come here for.
If you're looking to normalize all path separators (possibly for string work), here's what you need.
All the code segments have the node.js built-in module path imported to the path variable.
They also have the variable they work from stored in the immutable variable str, unless otherwise specified.
If you have a string, here's a quick one-liner normalize the string to a forward slash (/):
const answer = path.resolve(str).split(path.sep).join("/");
You can normalize to any other separator by replacing the forward slash (/).
If you want just an array of the parts of the path, use this:
const answer = path.resolve(str).split(path.sep);
Once you're done with your string work, use this to create a path able to be used:
const answer = path.resolve(str);
From an array, use this:
// assume the array is stored in constant variable arr
const answer = path.join(...arr);
I recommend against this, as it is patching node itself, but... well, no changes in how you require things.
(function() {
"use strict";
var path = require('path');
var oldRequire = require;
require = function(module) {
var fixedModule = path.join.apply(path, module.split(/\/|\\/));
oldRequire(fixedModule);
}
})();
This is the approach I use, to save some processing:
const path = require('path');
// normalize based on the OS
const normalizePath = (value: string): string {
return path.sep === '\'
? value.replace(/\\/g, '/')
: value;
}
console.log('abc/def'); // leaves as is
console.log('abc\def'); // on windows converts to `abc/def`, otherwise leave as is
Windows uses \, Linux and mac use / for path prefixes
For Windows : 'C:\\Results\\user1\\file_23_15_30.xlsx'
For Mac/Linux: /Users/user1/file_23_15_30.xlsx
If the file has \ - it is windows, use fileSeparator as \, else use /
let path=__dirname; // or filePath
fileSeparator=path.includes('\')?"\":"/"
newFilePath = __dirname + fileSeparator + "fileName.csv";
Use path module
const path = require("path");
var str = "test\test1 (1).txt";
console.log(str.split(path.sep)) // This is only on Windows

Get file name from absolute path in Nodejs?

How can I get the file name from an absolute path in Nodejs?
e.g. "foo.txt" from "/var/www/foo.txt"
I know it works with a string operation, like fullpath.replace(/.+\//, ''),
but I want to know is there an explicit way, like file.getName() in Java?
Use the basename method of the path module:
path.basename('/foo/bar/baz/asdf/quux.html')
// returns
'quux.html'
Here is the documentation the above example is taken from.
To get the file name portion of the file name, the basename method is used:
var path = require("path");
var fileName = "C:\\Python27\\ArcGIS10.2\\python.exe";
var file = path.basename(fileName);
console.log(file); // 'python.exe'
If you want the file name without the extension, you can pass the extension variable (containing the extension name) to the basename method telling Node to return only the name without the extension:
var path = require("path");
var fileName = "C:\\Python27\\ArcGIS10.2\\python.exe";
var extension = path.extname(fileName);
var file = path.basename(fileName,extension);
console.log(file); // 'python'
var path = require("path");
var filepath = "C:\\Python27\\ArcGIS10.2\\python.exe";
var name = path.parse(filepath).name;
console.log(name); //python
var base = path.parse(filepath).base;
console.log(base); //python.exe
var ext = path.parse(filepath).ext;
console.log(ext); //.exe
For those interested in removing extension from filename, you can use
https://nodejs.org/api/path.html#path_path_basename_path_ext
path.basename('/foo/bar/baz/asdf/quux.html', '.html');
If you already know that the path separator is / (i.e. you are writing for a specific platform/environment), as implied by the example in your question, you could keep it simple and split the string by separator:
'/foo/bar/baz/asdf/quux.html'.split('/').pop()
That would be faster (and cleaner imo) than replacing by regular expression.
Again: Only do this if you're writing for a specific environment, otherwise use the path module, as paths are surprisingly complex. Windows, for instance, supports / in many cases but not for e.g. the \\?\? style prefixes used for shared network folders and the like. On Windows the above method is doomed to fail, sooner or later.
path is a nodeJS module meaning you don't have to install any package for using its properties.
import path from 'path'
const dir_name = path.basename('/Users/Project_naptha/demo_path.js')
console.log(dir_name)
// returns
demo_path.js
In NodeJS, __filename.split(/\|//).pop() returns just the file name from the absolute file path on any OS platform.
Why need to care about remembering/importing an API while this regex approach also letting us recollect our regex skills.
So Nodejs comes with the default global variable called '__fileName' that holds the current file being executed
My advice is to pass the __fileName to a service from any file , so that the retrieval of the fileName is made dynamic
Below, I make use of the fileName string and then split it based on the path.sep. Note path.sep avoids issues with posix file seperators and windows file seperators (issues with '/' and '\'). It is much cleaner. Getting the substring and getting only the last seperated name and subtracting it with the actulal length by 3 speaks for itself.
You can write a service like this (Note this is in typescript , but you can very well write it in js )
export class AppLoggingConstants {
constructor(){
}
// Here make sure the fileName param is actually '__fileName'
getDefaultMedata(fileName: string, methodName: string) {
const appName = APP_NAME;
const actualFileName = fileName.substring(fileName.lastIndexOf(path.sep)+1, fileName.length - 3);
//const actualFileName = fileName;
return appName+ ' -- '+actualFileName;
}
}
export const AppLoggingConstantsInstance = new AppLoggingConstants();

Retrieving files from Directory Node Js

I am using readDirSync to get the files from a Diretory. PLease find the code and error as following.
var fs = require('fs');
var files = fs.readdirSync('./application/models/');
for(var i in files) {
var definition = require('../application/models/'+files[i]).Model;
console.log('Model Loaded: ' + files[i]);
}
I am getting error for line number 2 .
ENOENT, No such file or directory './application/models/' at Object.readdirSync (fs.js:376:18)
I have application/models on the same dir. I already checked for '/application/models/' and
'application/models/' but failed. I can see the same thing running on server.
Please help
Thanks
If you are using relative path when calling readdirSync, make sure it is relative to process.cwd().
However, "require" should be relative to the current script.
For example, given the following structure
server.js (node process)
/lib/importer.js (the current script)
/lib/application/models/
you may need to write importer.js as:
var fs = require('fs');
var files = fs.readdirSync('./lib/application/models/');
for (var i in files) {
var definition = require('./application/models/' + files[i]).Model;
console.log('Model Loaded: ' + files[i]);
}
Have you tried the following?
var files = fs.readdirSync(__dirname+'/application/models/');

Resources