Get directory of a file name in Javascript - javascript

How to get the directory of a file?
For example, I pass in a string
C:\Program Files\nant\bin\nant.exe
I want a function that returns me
C:\Program Files\nant\bin
I would prefer a built in function that does the job, instead of having manually split the string and exclude the last one.
Edit: I am running on Windows

I don't know if there is any built in functionality for this, but it's pretty straight forward to get the path.
path = path.substring(0,path.lastIndexOf("\\")+1);

If you use Node.js, path module is quite handy.
path.dirname("/home/workspace/filename.txt") // '/home/workspace/'

Use:
var dirname = filename.match(/(.*)[\/\\]/)[1]||'';
*The answers that are based on lastIndexOf('/') or lastIndexOf('\') are error prone, because path can be "c:\aa/bb\cc/dd".
(Matthew Flaschen did took this into account, so my answer is a regex alternative)

There's no perfect solution, because this functionality isn't built-in, and there's no way to get the system file-separator. You can try:
path = path.substring(0, Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\")));
alert(path);

Path module has an inbuilt function
Yes, the inbuilt module path has dirname() function, which would do the job for you.
const path = require("path");
file_path = "C:\\Program Files\\nant\\bin\\nant.exe" \\windows path
file_path = "C:/Program Files/nant/bin/nant.exe" \\linux path
path.dirname(file_path); \\gets you the folder path based on your OS
I see that your path is neither windows nor Linux compatible. Do not hardcode path; instead, take a reference from a path based on your OS.
I generally tackle such situations by creating relative paths using path.join(__dirname, "..", "assets", "banner.json");.
This gives me a relative path that works regardless of the OS you are using.

function getFileDirectory(filePath) {
if (filePath.indexOf("/") == -1) { // windows
return filePath.substring(0, filePath.lastIndexOf('\\'));
}
else { // unix
return filePath.substring(0, filePath.lastIndexOf('/'));
}
}
console.assert(getFileDirectory('C:\\Program Files\\nant\\bin\\nant.exe') === 'C:\\Program Files\\nant\\bin');
console.assert(getFileDirectory('/usr/bin/nant') === '/usr/bin');

Sorry to bring this back up but was also looking for a solution without referencing the variable twice. I came up with the following:
var filepath = 'C:\\Program Files\\nant\\bin\\nant.exe';
// C:\Program Files\nant\bin\nant.exe
var dirpath = filepath.split('\\').reverse().splice(1).reverse().join('\\');
// C:\Program Files\nant\bin
This is a bit of a walk through manipulating a string to array and back but it's clean enough I think.

filepath.split("/").slice(0,-1).join("/"); // get dir of filepath
split string into array delimited by "/"
drop the last element of the array (which would be the file name + extension)
join the array w/ "/" to generate the directory path
such that
"/path/to/test.js".split("/").slice(0,-1).join("/") == "/path/to"

And this?
If isn't a program in addressFile, return addressFile
function(addressFile) {
var pos = addressFile.lastIndexOf("/");
pos = pos != -1 ? pos : addressFile.lastIndexOf("\\");
if (pos > addressFile.lastIndexOf(".")) {
return addressFile;
}
return addressFile.substring(
0,
pos+1
);
}
console.assert(getFileDirectory('C:\\Program Files\\nant\\bin\\nant.exe') === 'C:\\Program Files\\nant\\bin\\');
console.assert(getFileDirectory('/usr/bin/nant') === '/usr/bin/nant/');
console.assert(getFileDirectory('/usr/thisfolderhaveadot.inhere') === '/usr/');

The core Javascript language doesn't provide file/io functions. However if you're working in a Windows OS you can use the FileSystemObject (ActiveX/COM).
Note: Don't use this in the client script-side script of a web application though, it's best in other areas such as in Windows script host, or the server side of a web app where you have more control over the platform.
This page provides a good tutorial on how to do this.
Here's a rough example to do what you want:
var fso, targetFilePath,fileObj,folderObj;
fso = new ActiveXObject("Scripting.FileSystemObject");
fileObj = fso.GetFile(targetFilePath);
folderObj=fileObj.ParentFolder;
alert(folderObj.Path);

Related

How to complete file pathname using javascript

Is it possible (and how) to create a file path if I know part of file pathname?
For example I have file pathname /User/Documents/Italy/Report_123.pdf
How to complete pathname if I know there is pdf in folder Italy which contain word Report_ those numbers at the end are dynamic?
I need to complete this task in javascript. Thanks in advance.
if you're using node.js, you can get all the files from that folder, then you iterate that result array to get the one you want.
import { readdir } from 'fs/promises';
const result = await readdir('C:/User/Documents/Italy');
console.log(result);
use this it may be helps you
var documentName = "Report_123.pdf"; // Use documentName Variable to use other js functions for example - documentName.split("_").
var path = "../User/Documents/Italy/"+documentName;

Normalize file path in JavaScript front-end

The short story:
Is there simple way to normalize file path in JavaScript, like in Java we have Paths.get("/a/b/../c").normalize() so /a/../../c would become /c. I seen many same questions here, but they are Node.js solutions, and I need pure JS or JQuery approach so it can be used in browser.
The long story:
I have a file server with web UI, that allows to browse files and download them. UI is written in spring and accessible at mysite.com/ui/
The file storage located at mysite.com/files/ which is plain Apache directory, so its possible to get direct link to file.
The real storage directory on server is /var/www/files
Path passing to back-end as mysite.com/ui/?path=/a/../../c, so back-end will normalize path variable separately to /c and then append it to base dir and so retrieving content of /home/storage/c, so it works perfectly.
The problem comes when user tries to download file like this with direct link. I.e. if user tries to download /a/../../c/d file from file server root, it appending to base storage url, which mysite.com/files/, and it becomes mysite.com/files/a/../../c/d so it will point to /var/www/d instead of /var/www/files/d so file can't be downloaded even if it is visible from web UI.
So I need to normalize relative file path first on front-end like on back-end when retrieving content of directory but I don't know how it can be done in JS. Is there function for it, or I have to write my own one?
So I ended up writing my own function on JS. It might be not what "path normalization" stands for, but anyway its exactly what I need
function normalizePath(path) {
// remove multiple slashes
path = path.replace(/\/+/g, '/');
// remove leading slash, will be added further
if (path.startsWith("/"))
path = path.substring(1)
// remove trailing slash
if (path.endsWith("/"))
path = path.slice(0, -1);
let segments = path.split("/");
let normalizedPath = "/";
for (let segmentIndex = 0; segmentIndex < segments.length; segmentIndex++) {
if (segments[segmentIndex] === "." || segments[segmentIndex] === "") {
// skip single dots and empty segments
continue;
}
if (segments[segmentIndex] === "..") {
// go up one level if possible
normalizedPath = normalizedPath.substring(0, normalizedPath.lastIndexOf("/") + 1);
continue;
}
// append path segment
if (!normalizedPath.endsWith("/"))
normalizedPath = normalizedPath + "/"
normalizedPath = normalizedPath + segments[segmentIndex];
}
return normalizedPath;
}
Still, I won't mark this as accepted answer as it's more of a quick fix, and I'm not JS expert so it definitely must be more elegant solution.

list all the files with the same extension as specified by the user

prints a list of files in a given directory, filtered by the extension of the files. The first argument will be the path to the directory we want to filter on, and the second argument, the type of the file that we need to print,
we must use readdir function .
like running this:
node fileJS.js /Users/admin/Desktop .docx
I've tried this code, but it will no return anything, for some reason.
can you please help me
var fs = require('fs'); //require node filesystem module
var path = require('path'); //require node path module (a couple of tools for reading path names)
var pathSupplied = process.argv[2];
var extFilter = process.argv[3];
function extension(element) {
var extName = path.extname(element);
return extName === '.' + extFilter;
};
fs.readdir(pathSupplied, function(err, list) {
list.filter(extension).forEach(function(value) {
console.log(value);
});
});
The problem is when you provide the extension argument starting with a . because in your filter function (extension) you are adding another dot when comparing (line: return extName === '.' + extFilter;).
Just invoke your current script like this:
node fileJS.js /Users/admin/Desktop docx
Or update your filter function to assume extFilter is provided with a starting dot.
Invoke the command like this:
node fileJS.js /Users/admin/Desktop docx
...without the dot in front of the extension you're looking for. Your code works then, I just tested it.

How to convert local file path to a file::?/ url safely in node.js?

I have local file paths (in node.js) and I need to convert them into file:// urls.
I'm now looking at https://en.wikipedia.org/wiki/File_URI_scheme and I feel this must be a solved problem and somebody must have a snippet or npm module to do this.
But then I try to search npm for this but I get so much cruft it is not funny (file, url and path are a search hit in like every package ever :) Same with google and SO.
I can do this naïve approach
site = path.resolve(site);
if (path.sep === '\\') {
site = site.split(path.sep).join('/');
}
if (!/^file:\/\//g.test(site)) {
site = 'file:///' + site;
}
But I'm pretty sure that is not the way to go.
Node.js v10.12.0 just got two new methods to solve this issue:
const url = require('url');
url.fileURLToPath(url)
url.pathToFileURL(path)
Documentation
https://nodejs.org/api/url.html#url_url_pathtofileurl_path
https://nodejs.org/api/url.html#url_url_fileurltopath_url
Use the file-url module.
npm install --save file-url
Usage:
var fileUrl = require('file-url');
fileUrl('unicorn.jpg');
//=> file:///Users/sindresorhus/dev/file-url/unicorn.jpg
fileUrl('/Users/pony/pics/unicorn.jpg');
//=> file:///Users/pony/pics/unicorn.jpg
Also works in Windows. And the code is simple enough, in case you want to just take a snippet:
var path = require('path');
function fileUrl(str) {
if (typeof str !== 'string') {
throw new Error('Expected a string');
}
var pathName = path.resolve(str).replace(/\\/g, '/');
// Windows drive letter must be prefixed with a slash
if (pathName[0] !== '/') {
pathName = '/' + pathName;
}
return encodeURI('file://' + pathName);
};
I had a similar issue, but the solution ended up being to use the new WHATWG URL implementation:
const path = 'c:\\Users\\myname\\test.swf';
const u = new URL(`file:///${path}`).href;
// u = 'file:///c:/Users/myname/test.swf'

iOS Phonegap Media Object - How do I access a resource in the WWW folder?

I'm developing an application with phonegap, and I have a sound file I want to play that's in a path like so www/Sounds/sound.mp3, and I'm trying to access this file using the Media object of Phonegap in order to play it.
I cannot figure out the path to access this sound file within a javascript file that uses the Media object? I've tried paths like, file:///www/Sounds/sound.mp3, relative paths, etc and I cannot access it. I keep getting the following error in xcode 4
Will attempt to use file resource 'file:///www/Sounds/sound.mp3'
Unknown resource 'file:///www/Sounds/sound.mp3'
What path do I need to use to access the file? Or do I need to copy the sound file out of my www directory and into my Resources folder and access it there?
My WWW folder is referenced, not sure if that makes a difference.
Heres a modified version of getPhoneGapPath that works for me on both iOS and Android. It is also not restricted to only working on files that have a filename that is 10 characters long :)
getPhoneGapPath: function () {
'use strict';
var path = window.location.pathname;
var phoneGapPath = path.substring(0, path.lastIndexOf('/') + 1);
return phoneGapPath;
}
var resource = getPhoneGapPath() + 'audio/audio.mp3';
getPhoneGapPath() will return:
iOS: /var/mobile/Applications/{GUID}/{appName}/www/
Android: /android_asset/www/
Use window.location.pathname to get the path of your application. It will look something like this on iPhone:
/var/mobile/Applications/{GUID}/{appname}.app/www/index.html
And this on Android:
/android_asset/www/index.html
Strip off the /index.html, prepend file://, and append your relative path Sounds/sound.mp3.
Here's something to get you started:
Demo: http://jsfiddle.net/ThinkingStiff/chNVY/
Code:
function getPhoneGapPath() {
var path = window.location.pathname;
path = path.substr( 0, path.length - 10 );
return 'file://' + path;
};
var resource = getPhoneGapPath() + 'Sounds/sound.mps';
The best answer is outdated. You are now able to play wav, mp3, and caf formats on iOS using this "relative path" method:
var media = new Media('beep.wav', ...);
Note that the above code requires the sound file to be in the root of your www/ directory -- in this example at www/beep.wav. If you want to put them in a subdiretory like www/sounds/, you'll need to specify it using a path relative to your www/ directory. For example, this also works now:
var media = new Media('sounds/beep.wav', ...);
for the sound file at www/sounds/beep.wav.
As of Cordova 3.3+, the 2 other answers aren't correct. It should work even if you just pass it a file name.
But, it will only work in iOS if the file extension is .wav.
This will work:
var media = new Media('recording.wav', ...);
This won't:
var media = new Media('recording.mp3', ...);
I had the same problem and all the answers about file paths alone didn't work for me using the Phone Gap Developer app. The problem was with the Developer app not pushing the files physically onto the device, preventing me from accessing them in any way.
The Media plugin worked as intended using
$ phonegap run android
$ phonegap run ios
with this js code:
function getPhoneGapPath() {
var path = window.location.pathname;
var phoneGapPath = path.substring(0, path.lastIndexOf('/') + 1);
return phoneGapPath;
}
var sound = new Media(getPhoneGapPath()+"assets/sounds/sound.mp3"
//...
sound.play();
This returns an error on Developer app:
'Cannot use audio file from source var/mobile/Containers/data/Application/{GUID}/Library/NoCloud/phonegapdevapp/www/assets/sounds/sound.mp3'
but works if built from the console.
Details can be found here:
https://forums.adobe.com/thread/2135718
Better try this to take into account any HTML5 History API code that might add in history entries with directories ("/"):
function get_phonegap_path () {
var path = window.location.pathname
return path.slice(0, path.indexOf("/www/") + 5)
}

Categories

Resources