Unable to fetch all text file names recursively from a directory - javascript

I'm trying to fetch all text files from a directory in a recursive manner (i.e. search all sub-folders):
let fs = require("fs");
function getPathNames(dirName) {
let pathNames = [];
for (let fileName of fs.readdirSync(dirName)) {
let pathName = dirName + "/" + fileName;
if (fs.statSync(pathName).isDirectory())
pathNames.concat(getPathNames(pathName));
else if (pathName.endsWith(".txt"))
pathNames.push(pathName);
}
return pathNames;
}
However, when I call getPathNames("."), I get only the name of the first file.
It works fine if I take the return-value out of the function, and update a global variable instead:
let fs = require("fs");
let pathNames = [];
function getPathNames(dirName) {
for (let fileName of fs.readdirSync(dirName)) {
let pathName = dirName + "/" + fileName;
if (fs.statSync(pathName).isDirectory())
getPathNames(pathName);
else if (pathName.endsWith(".txt"))
pathNames.push(pathName);
}
}
Does anyone spot anything wrong with the first method?

Well, concat is not an in place mutation, but returns you a new array instead, so I would say you should do this instead
pathNames = pathNames.concat(getPathNames(pathName));

Related

fs.readFileSync & path

I am relatively new to Node.js and have been looking around but cannot find a solution.
I want to read files from a subfolder 'filesPath'. I don't know how to write fs.readFileSync correctly
That is my idea. It works as let pdffile = fs.readFileSync(files[i]), but does not works as let pdffile = fs.readFileSync(filesPath, files[i]). Can you help me?
In example array is empty, but I cllect them in previous step.
var fs = require('fs')
const filesPath = path.join(__dirname, '/downloaded_files')
var files = []
function getNumbersAndPin() {
for (let i = 0; i < files.length; i++) {
let pdffile = fs.readFileSync(filesPath, files[i])
//let pdffile = fs.readFileSync(files[i]) //It works but looks for files in __dirname
pdfparse(pdffile).then(function (data) {
console.log(data.text.slice(-23))
})
}
}
setTimeout(getNumbersAndPin, 3000)
Check the documentation https://nodejs.org/api/fs.html#fsreadfilesyncpath-options. The second argument to readFileSync expects "options", not a file name or alike. Furthermore, your "files" array is empty.
As mentioned in a comment, you need to call path.join again. From this:
let pdffile = fs.readFileSync(filesPath, files[i])
to
let filePath = path.join(filesPath, '/', files[i])
let pdffile = fs.readFileSync(filePath)

How to read a file from an Azure Function in NodeJS?

I have an Azure function and a file called configAPI.json which are located in the same folder as shown in the image below.
I want to read the latter with the following code based on this post How can i read a Json file with a Azure function-Node.js but the code isn't working at all because when I try to see if there's any content in the configAPI variable I encounter undefined:
module.exports = async function (context, req) {
const fs = require('fs');
const path = context.executionContext.functionDirectory + '//configAPI.json';
configAPI= fs.readFile(path, 'utf-8', function(err, data){
if (err) {
context.log(err);
}
var result = JSON.parse(data);
return result
});
for (let file_index=0; file_index<configAPI.length; file_index++){
// do something
}
context.log(configAPI);
}
What am I missing in the code to make sure I can read the file and use it in a variable in my loop?
functionDirectory - give you path to your functionS app then you have your single function
I think you should do:
const path = context.executionContext.functionDirectory + '\\configAPI.json';
In case you want to parse your json file you should have:
const file = JSON.parse(fs.readFileSync(context.executionContext.functionDirectory + '\\configAPI.json'));
PS. context has also variable functionName so other option to experiment would be:
const path = context.executionContext.functionDirectory +
+ '\\' +context.executionContext.functionName + '\\configAPI.json';

Is there a way to unzip a file from a url request and parse its content in node?

I want to download a zip file from a url and parse its contents in node. I do not want to save the file on disk. The zip file is a directory of csv files that I want to process. How can I approach this? The only package that has an option for unzipping from a URL is unzipper but it does not work for me. Every other package lets you unzip a file on disk by providing the path to the file but not a url.
I am downloading the file like so:
const res = await this.get(test)
But what can I do now? There are packages like AdmZip that can extract zip files but need a path as a string to a file on disk. Is there a way I can pass/ stream my res object above to the below?
var AdmZip = require('adm-zip');
// reading archives
var zip = new AdmZip("./my_file.zip");
var zipEntries = zip.getEntries(); // an array of ZipEntry records
zipEntries.forEach(function(zipEntry) {
console.log(zipEntry.toString()); // outputs zip entries information
if (zipEntry.entryName == "my_file.txt") {
console.log(zipEntry.getData().toString('utf8'));
}
});
Here's a simple example of downloading a .zip file and unzipping using adm-zip. As #anonymouze points out, you can pass a buffer to the AdmZip constructor.
const axios = require("axios");
const AdmZip = require('adm-zip');
async function get(url) {
const options = {
method: 'GET',
url: url,
responseType: "arraybuffer"
};
const { data } = await axios(options);
return data;
}
async function getAndUnZip(url) {
const zipFileBuffer = await get(url);
const zip = new AdmZip(zipFileBuffer);
const entries = zip.getEntries();
for(let entry of entries) {
const buffer = entry.getData();
console.log("File: " + entry.entryName + ", length (bytes): " + buffer.length + ", contents: " + buffer.toString("utf-8"));
}
}
getAndUnZip('https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-zip-file.zip');
In this case I'm simply using axios to download a zip file buffer, then parsing it with AdmZip.
Each entry's data can be accessed with entry.getData(), which will return a buffer.
In this case we'll see an output something like this:
File: sample.txt, length (bytes): 282, contents: I would love to try or hear the sample audio your app can produce. I do...
Here's another example, this time using node-fetch:
const fetch = require('node-fetch');
const AdmZip = require('adm-zip');
async function get(url) {
return fetch(url).then(res => res.buffer());
}
async function getAndUnZip(url) {
const zipFileBuffer = await get(url);
const zip = new AdmZip(zipFileBuffer);
const entries = zip.getEntries();
for(let entry of entries) {
const buffer = entry.getData();
console.log("File: " + entry.entryName + ", length (bytes): " + buffer.length + ", contents: " + buffer.toString("utf-8"));
}
}
getAndUnZip('https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-zip-file.zip');

get file name of selected file

How can I get only the name of the selected Data. I do the following but get the whole path of the File. I would like to display the filename for the user
var dialog = require('electron').remote.dialog;
var url;
document.getElementById('openButton').onclick = () => {
dialog.showOpenDialog((fileName) => {
if(fileName === undefined) {
alert('No file selected');
} else {
console.log(fileName)
url = fileName[0];
console.log(url);
$('#dataFileName').html(url)
}
})
};
What i get is "/Users/void/Desktop/abc.xlsx" and I would like to have in addition to that only the file i opened.
You can also use path.basename()
const {basename} = require('path')
let filePath = "/Users/void/Desktop/abc.xlsx"
let fileName = basename(filePath)
Here is a simple way you can grab just the file name:
var filePath = "/Users/void/Desktop/abc.xlsx";
var fileName = filePath.replace(/^.*[\\\/]/, '');
console.log(fileName);
Here is a fiddle to demonstrate.
If I understood correctly, you can use this:
var mystring = "/Users/void/Desktop/abc.xlsx"; //replace your string
var temp = mystring.split("/"); // split url into array
var fileName = temp[temp.length-1]; // get the last element of the array
What you basically do is to split your url with "/" regex, so you get each bit, and filename is always the last bit so you can get it with array's length you just created.

Cannot call method 'push' of undefined when appending JSON Array

Keep getting a error that I can't push a JSON object to a JSON array. Only changes I made was that I this function is in a different file and so I called it as a module.
index.js
var mods = require('../server/api/getUserMods.js');
var usernamePerms = [ 'settings', 'mod1', 'mod2' ]
console.log(mods.getUserMods(usernamePerms));
getUserMods.js
var fs = require('fs');
exports.getUserMods = function(input) {
var umkModules = '../umk_modules/';
var modules = '{"module":[]}';
var moduleParse = JSON.parse(modules);
for (i = 0; i < input.length; i++) {
console.log("Parsing: " + input[i]);
console.log("At: " + umkModules.concat(input[i],"/","module-view.json"));
console.log();
var readModule = JSON.parse(fs.readFileSync(umkModules.concat(input[i],"/","module-view.json"), 'utf8'));
console.log(readModule);
moduleParse['modules'].push(readModule);
};
modules = JSON.stringify(moduleParse);
return modules;
};
The function getUserMods takes a array strings and searches within a specified file path finding a file called module-view.json then appending it to the empty JSON array.
When ran, I get this...
moduleParse['modules'].push(readModule);
moduleParse['module'].push(readModule);
Your property is named module, not modules. And I'm not entirely sure why you'd use JSON when you can simply do:
var moduleParse = {
module:[]
}

Categories

Resources