create file using JS for browser - javascript

could someone tell me how can I create a file using JS for browser? Is there a way to do that without Node JS? I was trying to create a file using Node JS, fs command, but said that "fs.createWriteStream is not a function".

You can use File System Access API
For example according to MDN
// store a reference to our file handle
let fileHandle;
async function getFile() {
// open file picker
[fileHandle] = await window.showOpenFilePicker();
if (fileHandle.kind === 'file') {
// run file code
} else if (fileHandle.kind === 'directory') {
// run directory code
}
}
here is the useful link

Related

Get file extention using only file name in javascript

I am creating a discord bot (irrelevent) that sends images into the chat. The user can type out the name of the image without needing to type the file extention. The problem is that the bot doesn't know what the file extention is so it will crash if the picture is a .jpg and the program was expecting a .png. Is there a way to make the program not require a file extention to open the file?
let image = imageName;
message.channel.send({ files: [`media/stickers/${imageName}.png`] });
Unfortunately, the extension of the filename is required. You know file.mp4 and file.mp3 is entirely different.
However, you can use a try-except and a for loop to get the correct file!
I would suggest:
let image = imageName;
let extensions = [".png", ".jpg", "gif"] // All the extensions you can think of
const pass = () => {}
for (const extension of extensions) {
try {
message.channel.send({ files: [`media/stickers/${imageName}${extension}`] }); // successfully get file and send
break
} catch(error) {
pass() // do nothing, and go back to the loop and test other extension
}
}
I haven't tried that before, and I am a Python programmer. But I hope you get the idea.
Using fs - specifically the Promise version of fs, makes this quite simple
import { readdir } from 'fs/promises';
const getFullname = async (path, target) =>
(await readdir(path))
.find(file =>
file === target || file.split('.').slice(0,-1).join('.') === target
);
try {
const actualName = await getExtension('media/stickers', imageName);
if (!actualName) {
throw `File ${imageName} not found`;
}
message.channel.send({ files: [`media/stickers/${actualName}`] });
} catch(error) {
// handle your errors here
}
You can pass in the name with or without the extension and it will be found - note, this is NOT case insensitive ... so XYZ won't match xyz.jpg - easily changed if you need case insensitivity
There are only a few known image extensions like jpg, png, gif, jpeg. Maybe try and fetch the file with best guess extension, if it throws exception try the next format.

Reading a parquet file in nodejs

I am trying the following code (from sample of parquetjs-lite and stackoverflow) to read a parquet file in nodejs :
const readParquetFile = async () => {
try {
// create new ParquetReader that reads from test.parquet
let reader = await parquet.ParquetReader.openFile('test.parquet');
}
catch (e){
console.log(e);
throw e;
}
// create a new cursor
let cursor = reader.getCursor();
// read all records from the file and print them
let record = null;
while (record = await cursor.next()) {
console.log(record);
}
await reader.close();
};
When I run this code nothing happens . There is nothing written to the console, for testing purpose I have only used a small csv file which I converted using python to parquet.
Is it because I have converted from csv to parquet using python (I couldn't find any JS equivalent for large files on which I have to ultimately be able to use).
I want my application to be able to take in any parquet file and read it. Is there any limitation for parquetjs-lite in this regard.
There are NaN values in my CSV could that be a problem ?
Any pointers would be helpful.
Thanks
Possible failure cases are
you are calling this function in some file without a webserver running.
In this case the file will run in async mode and as async function goes in callback stack and your main stack is empty the program will end and even is you have code in your call stack it will never run or log anything.
To solve this try running a webserver or better use sync calls
//app.js (without webserver)
const readParquetFile = async () => {
console.log("running")
}
readParquetFile()
console.log("exit")
when you run the above code the output will be
exit
//syncApp.js
const readParquetFile = () => {
console.log("running")
// all function should be sync
}
readParquetFile()
console.log("exit")
here the console log will be
running
exit

What is the best way to keep a file open to read/write?

I have a local JSON file which I intent to read/write from a NodeJS electron app. I am not sure, but I believe that instead of using readFile() and writeFile(), I should get a FileHandle to avoid multiple open and close actions.
So I've tried to grab a FileHandle from fs.promises.open(), but the problem seems to be that I am unable to get a FileHandle from an existing file without truncate it and clear it to 0.
const { resolve } = require('path');
const fsPromises = require('fs').promises;
function init() {
// Save table name
this.path = resolve(__dirname, '..', 'data', `test.json`);
// Create/Open the json file
fsPromises
.open(this.path, 'wx+')
.then(fileHandle => {
// Grab file handle if the file don't exists
// because of the flag 'wx+'
this.fh = fileHandle;
})
.catch(err => {
if (err.code === 'EEXIST') {
// File exists
}
});
}
Am I doing something wrong? Are there better ways to do it?
Links:
https://nodejs.org/api/fs.html#fs_fspromises_open_path_flags_mode
https://nodejs.org/api/fs.html#fs_file_system_flags
Because JSON is a text format that has to be read or written all at once and can't be easily modified or added onto in place, you're going to have to read the whole file or write the whole file at once.
So, your simplest option will be to just use fs.promises.readFile() and fs.promises.writeFile() and let the library open the file, read/write it and close the file. Opening and closing a file in a modern OS takes advantage of disk caching so if you're reopening a file you just previously opened not long ago, it's not going to be a slow operation. Further, since nodejs performs these operations in secondary threads in libuv, it doesn't block the main thread of nodejs either so its generally not a performance issue for your server.
If you really wanted to open the file once and hold it open, you would open it for reading and writing using the r+ flag as in:
const fileHandle = await fsPromises.open(this.path, 'r+');
Reading the whole file would be simple as the new fileHandle object has a .readFile() method.
const text = await fileHandle.readFile({encoding 'utf8'});
For writing the whole file from an open filehandle, you would have to truncate the file, then write your bytes, then flush the write buffer to ensure the last bit of the data got to the disk and isn't sitting in a buffer.
await fileHandle.truncate(0); // clear previous contents
let {bytesWritten} = await fileHandle.write(mybuffer, 0, someLength, 0); // write new data
assert(bytesWritten === someLength);
await fileHandle.sync(); // flush buffering to disk

Automating Priority-Web-SDK file upload

I would like to create a command line (or other automated) method for uploading files to priority using the Web-SDK. The best solution I have right now seems to be a simple webform activated by a python script.
Are there tools/examples for using Javascript and a file picker without opening the browser? Are there Priority-Web-SDK ports to other environments? C#, Python, etc?
Any other suggestions also welcome.
UPDATE June 14, 2020:
I was able to complete the task for this client using a combination of Javascript, Python and C#. A tangled mess indeed, but files were uploaded. I am now revisiting the task and looking for cleaner solutions.
I found a working and usable Node module to compact the program into an executable to make it a viable option for deployment.
So the question becomes more focused => creating the input for uploadDataUrl() or uploadFile() without a browser form.
You run node locally and use priority SDK.
*As long as you work in an environment that is capable to render JS.
You can send files through the function uploadFile.
The data inside the file object need to be written as 64 base file.
This nodejs script will upload a file to Priority. Make sure that fetch-base64 is npm installed:
"use strict";
const priority = require('priority-web-sdk');
const fetch = require('fetch-base64');
const configuration = {...};
async function uploadFile(formName, zoomVal, filepath, filename) {
try {
await priority.login(configuration);
let form = await priority.formStartEx(formName, null, null, null, 1, {zoomValue: zoomVal});
await form.startSubForm("EXTFILES", null ,null);
let data = await fetch.local(filepath + '/' + filename);
let f = await form.uploadDataUrl(data[0], filename.match(/\..+$/i)[0], () => {});
await form.fieldUpdate("EXTFILENAME", f.file); // Path
await form.fieldUpdate("EXTFILEDES", filename); // Name
await form.saveRow(0);
} catch(err) {
console.log('Something bad happened:');
console.dir(err);
}
}
uploadFile('AINVOICES', 'T9679', 'C:/my/path', 'a.pdf');

Handle concurrent writing to a file in JavaScript

I have two JavaScript file for reading and writing a common text file. Created a task scheduler to run this JavaScript file at same time. So i need to implement lock concept in scripts. Is there exists any lock concept in JavaScript ?
More Clarification on Question:
I am not using node.js. simply it is a jscript file.
There is two Jscript file, File A and File B.
Both files are configured by a task scheduler at a time 10 am.
Both files are reading a text file D.Updates some text and write again to it.
If there occurs any resource starvation like,
File A and File B are writing text file D at same time but different content.
try {
var objectFile = new ActiveXObject("Scripting.FileSystemObject");
var writingFile;
if(objectFile.FileExists(FileLocation))
{
var fileSpecified = objectFile.GetFile(FileLocation);
writingFile = fileSpecified.OpenAsTextStream( 8, 0 );
}
else
{
writingFile= objectFile.CreateTextFile(FileLocation, true);
}
writingFile.WriteLine(Date());
writingFile.WriteLine("test data");
writingFile.Close();
}
catch(e)
{
return true;
}
The FileSystemObject does not support file locking.
The best you can do is to delete the file before writing. Note that initially you have to create an empty file at FileLocation.
try {
var fso = new ActiveXObject("Scripting.FileSystemObject");
try {
fso.DeleteFile(FileLocation); // Will throw if file does not exist
var writingFile= fso.CreateTextFile(FileLocation);
writingFile.WriteLine(Date());
writingFile.WriteLine("test data");
writingFile.Close();
} catch(e) {
// File did not exist, so somebody is currently writing it.
}
}
catch(e)
{
return true;
}
There is also the append-trick, see
See also How can I determine if a file is locked using VBS?.
But this is not save to use if you do not want to append.

Categories