I am trying to get get the folder path from user's selection and for each file I read it and return the data. However upon getting the file I cannot read the data for some reason that I have't been able to understand yet. The directory I am trying to read and render do exist. I have referred to the other similar posts as well.
readFolder() {
dialog.showOpenDialog({ properties: ['openDirectory'] }, (dirFiles) => {
console.log(dirFiles);
if (dirFiles === undefined) {
console.log('No file ');
return;
}
const pathName = dirFiles[0];
fs.readdir(pathName, (err, files) => {
files.forEach(file => {
fs.readFile(file, 'utf-8', (err, data) => {
if (err) {
console.log(`something went wrong ${err}`);
} else {
console.log(data);
}
});
});
});
});
}
readdir returns filenames "a", "b", "c" etc. You want pathName + '/' + file for "/path/to/file/a"
The mistake I made was the fact that I hadn't realised the return values of 'file' which are just the names of the files as strings but not paths. Assinging let filePath =${pathName}/${file}; and reading it onwards solved the problem.
Related
Im using nodejs and multer to upload multiple images.
Firsat check is if dir exist. If not will be created.
Error: When folder doesnt exist all images are passing the first condition fs.access by giving the message "Directory doesnt exist" but then dir is created so the second image gets an error "Directory exist".
var storage = multer.diskStorage({
destination: (req, file, cb) => {
const userId = encryptFolder(req.params["id"]);
const dtrToCreate = "C:/Users/User/Pictures/" + userId;
fs.access(dtrToCreate, (error) => {
if (error) {
console.log("Directory does not exist.", userId);
fs.mkdirSync(dtrToCreate, (error, data) => {
if (error) {
throw error;
}
cb(null, "C:/Users/User/Pictures/");
});
} else {
console.log("Directory exists.", userId);
cb(null, "C:/Users/User/Pictures/");
}
});
},
When directory exist images are uploaded sucessfully.
Working solution:
Since there are multiple files should be a recusrsive function to check if folder exist each time files passing.
fs.mkdirSync(dtrToCreate, { recursive: true })
return cb(null, dtrToCreate)
I am writing in Node.js.
And the in console I see the file names, and after that many strings: "File written", and in file I see one string with first filename in folder
Q: How do I write to TXT file an array with filenames from folder in Javascript?
Here is my code:
const WebmUrl = new URL('file:///D:/MY PROJCT/webm/hlp.txt');
fs.readdirSync(testFolder).forEach(file => {
console.log(file)
fs.writeFile(WebmUrl, file, function(err){
if(err) {
console.log(err)
} else {
console.log('File written!');
}
});
})
When you use fs.writeFile you replace the file if it exists. So in your loop you are continuously making a one item file and then replacing it on the next iteration.
You can use fs.appendFileSync or fs.appendFile
For example:
const fs = require('fs')
fs.readdirSync(directory).forEach(file => {
fs.appendFileSync(filename, file, function(err){
})
})
You could also just make an array of filenames, join them into a string and write all at once.
const fs = require('fs')
let str = fs.readdirSync(directory).join('\n')
fs.writeFile(filename, str, function(err){
if(err) {
console.log(err)
} else {
console.log('File written!');
}
});
Or you can add the append flag {flag: 'as'} see https://nodejs.org/api/fs.html#fs_file_system_flags
fs.readdirSync('../checkouts').forEach(file => {
console.log(file)
fs.writeFile('./test.txt', `${file}\n` , {flag: 'as'}, function (err) {
if (err) { console.log(err) }
else { console.log('File written!'); }
});
})
I asked this question for PHP a long time ago. The same applies for Node.js the code below seems a little slow when using in a loop - is there a way for writing this in pure Node.js vanilla JavaScript without plugins or React.js etc?
const dirname = 'cdn-assets/'
fs.readdir(dirname, function(err, files) {
if (err) {
// some sort of error
} else {
if (!files.length) {
// directory appears to be empty
}
}
});
Also, can I write a further conditional to check:
if(directory_has_these_files('.js, .css, .jpg, .svg, .mp4'))
So if you do this
fs.readdir('/path/to/empty_dir', (data, err) => console.log(data, '.....', err))
You'll see that the result is:
null '.....' []
So your code can be simplified as
fs.readdir(dirname, (err, files) => {
if (err && !files) {
console.error(err)
}
console.info('the files --> ', files)
let regexp = RegExp('.jpeg|.doc|.png|.zip', 'gi')
for(result in files) {
if(regexp.test(files[result])) {
console.log('I have the following', files[result])
}
}});
However....
We want this quick, modern and efficient, don't we?!
So this is even better:
fs.readdir(dirname, (err, files) => {
if (err && !files) {
console.error(err)
}
let regexp = RegExp('.jpeg|.doc|.png|.zip', 'gi');
files.filter(
file => file.match(regexp)
).map(
result => console.log('I have the following',result)
);
});
One of the advantages to using a map on a directory, is that you'll guarantee the preservation of order, it also looks cleaner.
Map is built-in iterable — Object is not, this is not to say the Map is a replacement for Object, there are use cases for both. That's another story.
What i'm trying to do is read/write to multiple files at once, Once a file is created, only the data inside the file would be changed.
code:
var files = fs.readdirSync(__dirname+"/")
function readWrite(files) {
fs.readFile(files[i], 'utf-8', function(err, data){
if (err){
console.log(err)
}
fs.writeFile(files[i], 'test string', 'utf-8', function (err) {
if (err){
console.log("completed")
}
})
})
}
for(i in files){
readWrite(files[i])
}
The error is pretty obvious "path must be a string", But how do I go about writing to multiple files in the same directory at once?
I'm pretty new to node, so sorry if this seems like a bonehead question, any help would be appreciated.
You're passing filename to readWrite function so you should not use [i]:
function readWrite(file) {
fs.readFile(file, 'utf-8', function(err, data) {
if (err) {
console.log(err)
}
fs.writeFile(file, 'test string', 'utf-8', function (err) {
if (err) {
console.log("completed")
}
})
})
}
for (i in files) {
readWrite(files[i])
}
Try replacing files[i] by files inside your function. You should be using the name of your variable, files (and probably rename it to filepath)
After that, do you really want to read and write from the same file at the same time (this is what your code is doing) ?
I'm using the excellent Request library for downloading files in Node for a small command line tool I'm working on. Request works perfectly for pulling in a single file, no problems at all, but it's not working for ZIPs.
For example, I'm trying to download the Twitter Bootstrap archive, which is at the URL:
http://twitter.github.com/bootstrap/assets/bootstrap.zip
The relevant part of the code is:
var fileUrl = "http://twitter.github.com/bootstrap/assets/bootstrap.zip";
var output = "bootstrap.zip";
request(fileUrl, function(err, resp, body) {
if(err) throw err;
fs.writeFile(output, body, function(err) {
console.log("file written!");
}
}
I've tried setting the encoding to "binary" too but no luck. The actual zip is ~74KB, but when downloaded through the above code it's ~134KB and on double clicking in Finder to extract it, I get the error:
Unable to extract "bootstrap" into "nodetest" (Error 21 - Is a directory)
I get the feeling this is an encoding issue but not sure where to go from here.
Yes, the problem is with encoding. When you wait for the whole transfer to finish body is coerced to a string by default. You can tell request to give you a Buffer instead by setting the encoding option to null:
var fileUrl = "http://twitter.github.com/bootstrap/assets/bootstrap.zip";
var output = "bootstrap.zip";
request({url: fileUrl, encoding: null}, function(err, resp, body) {
if(err) throw err;
fs.writeFile(output, body, function(err) {
console.log("file written!");
});
});
Another more elegant solution is to use pipe() to point the response to a file writable stream:
request('http://twitter.github.com/bootstrap/assets/bootstrap.zip')
.pipe(fs.createWriteStream('bootstrap.zip'))
.on('close', function () {
console.log('File written!');
});
A one liner always wins :)
pipe() returns the destination stream (the WriteStream in this case), so you can listen to its close event to get notified when the file was written.
I was searching about a function which request a zip and extract it without create any file inside my server, here is my TypeScript function, it use JSZIP module and Request:
let bufs : any = [];
let buf : Uint8Array;
request
.get(url)
.on('end', () => {
buf = Buffer.concat(bufs);
JSZip.loadAsync(buf).then((zip) => {
// zip.files contains a list of file
// chheck JSZip documentation
// Example of getting a text file : zip.file("bla.txt").async("text").then....
}).catch((error) => {
console.log(error);
});
})
.on('error', (error) => {
console.log(error);
})
.on('data', (d) => {
bufs.push(d);
})