Using the Filesystem API of Tizen SDK, I'm getting a javascript File object that prints the following datas on console.log:
File
created: Thu Dec 14 2017 09:59:51 GMT+0100 (CET)
fullPath: "/opt/share/folder/image.jpg"
get fileSize: function fileSizeGetter() {var _realPath=commonFS_.toRealPath(this.fullPath);var _result=native_.callSync('File_statSync',{location:_realPath});var _aStatObj=native_.getResultObject(_result);return _aStatObj.isFile?_aStatObj.size:undefined;}
isDirectory: false
isFile: true
length: undefined
mode: "rw"
modified: Thu Dec 14 2017 09:59:51 GMT+0100 (CET)
name: "image.jpg"
parent: File
path: "/opt/share/folder/"
readOnly: false
set fileSize: function () {}
__proto__: File
Problem is that the length of the File is undefined. This cause my Filereader readyState to stay at 0 (EMPTY) state (or maybe the problem is somewhere else).
Why is my code returning undefined for length parameter?
My code:
tizen.filesystem.resolve('/opt/share/folder/image.jpg', function(file) {
console.log(file);
var reader = new FileReader();
console.log(reader);
reader.readAsArrayBuffer(file);
reader.onload = fileLoad;
reader.onerror = function(evt){
console.log(evt.target.error.name);
}
});
Console value for reader:
FileReader
constructor: FileReaderConstructor
error: null
onabort: null
onerror: function (evt) {
onload: function fileLoad(evt) {
onloadend: null
onloadstart: null
onprogress: null
readyState: 0
result: null
__proto__: FileReaderPrototype
Precision:
Using the file url to insert image in a canvas is working and the file is existing on device
According to the documentation, length is for File instances representing directories (it tells you how many files and directories the directory contains). For a File actually representing a file, you'd use fileSize.
I don't see a FileReader anywhere in the Tizen file system documentation. Instead, examples reading and writing files use a FileStream via openStream.
Related
i'm using file-saver package to download files. The downloading is not the issue it seems to be the opening of any file. I console.log file from the files function logic below and get this:
File {name: '5ece9322f34d050a92546892.jpeg', lastModified: 1641918175691, lastModifiedDate: Tue Jan 11 2022 16:22:55 GMT+0000 (Greenwich Mean Time), webkitRelativePath: '', size: 156, …}
lastModified: 1641918175691
lastModifiedDate: Tue Jan 11 2022 16:22:55 GMT+0000 (Greenwich Mean Time)
[[Prototype]]: Object
name: "5ece9322f34d050a92546892.jpeg"
size: 156
type: ".jpeg"
webkitRelativePath: ""
[[Prototype]]: File
I get the following error:
The file 5ece9322f34d050a92546892.jpeg could not be opened.It may be damaged or use a file format that Preview doesn’t recognise.
My code:
import { saveAs } from 'file-saver';
const files = ({url, fileName}) => {
const extension = url.slice(url.lastIndexOf('.'));
const handleDownloadDocument = (fileUrl, name, ex) => {
const file = new File([fileUrl], name, { type: ex });
return saveAs(file);
};
return(<div onClick={() => handleDownloadDocument(url, fileName, extension)}> download </div>);
};
I have a file that I upload using antdUpload
The html renderer :
<Upload
beforeUpload={((file: RcFile, fileList: RcFile[]): boolean => {this.requestUpload(file, (fileList.length || 0 )); return false;})}
></Upload>
The code part :
requestUpload(file: RcFile, nbFile: number): void {
const r = new FileReader();
r.onload = (): void => {
FileHelper.uploadFile({
filename: file.name,
filepath: `${this.props.datastoreId}/${this.props.itemId}/${this.props.fieldId}/${file.name}`,
file: r.result,
field_id: this.props.fieldId,
item_id: this.props.itemId || '',
d_id: this.props.datastoreId || '',
p_id: this.props.projectId || '',
display_order: nbFile
}).subscribe()
};
r.readAsArrayBuffer (file);
}
So I get an RcFile (which just extend the type file) from that moment, I don't know what to do to get a raw binary of the file. my API only work with a raw binary, and nothing else. so I need that file: r.result, to be a pure binary raw data.
I found other stackoverflow question, but they all say how it should be (using base64 or other) but not how to do it if you have no other option to change it.
How can I achieve this ?
According to the file-upload tool you linked (ng-file-upload) you should first: "Ask questions on StackOverflow under the 'ng-file-upload' tag." So, add that tag to this post.
Then if I Ctrl+F for "binary" on the docs, I see this:
Upload.http({
url: '/server/upload/url',
headers : {
'Content-Type': file.type
},
data: file
})
Looks like they're passing a file object as the data, and the w/e the file type is in the header. I haven't tried this though...
I have this function which I am trying to unit-test. It is called when a file is selected from HTML <input>. I am creating a FileReader which I suppose should fire load event. I want to call my function _handleReaderLoaded when load is fired.
handleFileSelect(files:ArrayLike<File>){
console.log("got file upload event: ");
console.log(" image attachment count: ",this.currentImageAttachmentCount);
if(this.currentImageAttachmentCount >= this.maxImageAttachmentCount)
{
console.log("reached max attachment size");
this.showDialog("You can't attach more files",new DialogContext("",""));
return;
}
console.log("files selected:",files);
console.log("total selected: ",files.length);
for(let i=0;i<files.length;i++)
{
console.log("files name:",files[i].name);
console.log("files object:",files[i])
}
//working with only 1 file at the moment
let file = files[0];
console.log("file at index 0 ",file);
if (files && file) {
console.log("reading file");
let reader:FileReader = new FileReader();
reader.onload =this._handleReaderLoaded.bind(this);
reader.onerror = this.debugPrintFileEvents.bind(this); //what is the purpose of bind and what does this refer to?
reader.onloadend = this.debugPrintFileEvents.bind(this);
reader.onloadstart = this.debugPrintFileEvents.bind(this);
reader.onprogress = this.debugPrintFileEvents.bind(this);
reader.onabort = this.debugPrintFileEvents.bind(this);
;
//The readAsBinaryString method is used to start reading the contents of the specified Blob or File.
reader.readAsBinaryString(file);
this.currentImageAttachmentCount++;
}
}
but I notice that the load event is not getting fired. The unit test case is
fit('should upload maximum 3 image files', () => {
let newPracticeQuestionComponent = component;
expect(newPracticeQuestionComponent.currentImageAttachmentCount).toBe(0);
let file1 = new File(["foo1"],"foo1.txt");
spyOn(newPracticeQuestionComponent,'_handleReaderLoaded');
spyOn(newPracticeQuestionComponent,'showDialog');
newPracticeQuestionComponent.handleFileSelect([file1]);
expect(newPracticeQuestionComponent.currentImageAttachmentCount).toBe(1);
});
The following are the debug prints in the browser window. You'll notice that there is no load event, thus my function _handleReaderLoaded is not getting executed
got file upload event:
context.js:1972 image attachment count: 0
context.js:1972 files selected: [File(4)]
context.js:1972 total selected: 1
context.js:1972 files name: foo1.txt
context.js:1972 files object: File(4) {name: "foo1.txt", lastModified: 1548101766552, lastModifiedDate: Mon Jan 21 2019 20:16:06 GMT+0000 (Greenwich Mean Time), webkitRelativePath: "", size: 4, …}
context.js:1972 file at index 0 File(4) {name: "foo1.txt", lastModified: 1548101766552, lastModifiedDate: Mon Jan 21 2019 20:16:06 GMT+0000 (Greenwich Mean Time), webkitRelativePath: "", size: 4, …}
context.js:1972 reading file
context.js:1972 got file reader event ProgressEvent {isTrusted: true, lengthComputable: true, loaded: 0, total: 4, type: "loadstart", …}
context.js:1972 got file reader event ProgressEvent {isTrusted: true, lengthComputable: true, loaded: 4, total: 4, type: "progress", …}
context.js:1972 got file reader event ProgressEvent {isTrusted: true, lengthComputable: true, loaded: 4, total: 4, type: "loadend", …}
Interestingly, if I change the onload handler to this
then I see that that handler is called
reader.onload = function(){
console.log('onload event for reader ',reader);
};
got file reader event ProgressEvent {isTrusted: true, lengthComputable: true, loaded: 0, total: 4, type: "loadstart", …}
context.js:1972 got file reader event ProgressEvent {isTrusted: true, lengthComputable: true, loaded: 4, total: 4, type: "progress", …}
context.js:1972 onload event for reader _global.(anonymous function) {__zone_symbol__originalInstance: FileReader} <<----- THIS GETS CALLED
context.js:1972 got file reader event ProgressEvent {isTrusted: true, lengthComputable: true, loaded: 4, total: 4, type: "loadend", …}
the _handleReaderLoaded method is
_handleReaderLoaded(event:FileReaderProgressEvent) {
console.log("got load event of file reader ",event);
let thumbnailTemplateViewRef:EmbeddedViewRef<any>;
/*
When the read operation is finished, the result attribute contains the raw binary data from the file.
*/
let binaryString = event.target.result;
this.base64textString= btoa(binaryString);
console.log(this.base64textString);
/*show image as thumbnail*/
let src = "data:image/png;base64,";
src += this.base64textString;
//create new ids for div, img and a in the template
++this.consecutiveIdGenerator;
let divId = "thumbnail-"+(this.consecutiveIdGenerator);
console.log("div id "+divId);
let imgId = "img-"+(this.consecutiveIdGenerator);
console.log("img id "+imgId);
let closeId = "close-button-"+(this.consecutiveIdGenerator)
console.log("close Id is "+closeId);
//TODOM - define context as a class so that it can be used in new question and question details
thumbnailTemplateViewRef = this.thumbnailContainerRef.createEmbeddedView(this.thumbnailTemplateRef,{option:{divId:divId,
imgId:imgId,
closeId:closeId,
imgSrc:src}});
//store the reference of the view in context of the template. This will be used later to retrive the index of the view when deleting the thumbnail
thumbnailTemplateViewRef.context.option.viewRefId = thumbnailTemplateViewRef;
}
Urrrg!!!! I am spying on _handleReaderLoaded, so obviously its original implementation will not be called! I should have used spyOn(newPracticeQuestionComponent,'_handleReaderLoaded').and.callThrough();
I want to know if it is possible to create a file object (name, size, data, ...) in NodeJS with the path of existing file ? I know that it is possible in client side but I see nothing for NodeJS.
In others words, I want the same function works in NodeJS :
function srcToFile(src, fileName, mimeType){
return (fetch(src)
.then(function(res){return res.arrayBuffer();})
.then(function(buf){return new File([buf], fileName, {type:mimeType});})
);
}
srcToFile('/images/logo.png', 'logo.png', 'image/png')
.then(function(file){
console.log(file);
});
And ouput will be like :
File {name: "logo.png", lastModified: 1491465000541, lastModifiedDate: Thu Apr 06 2017 09:50:00 GMT+0200 (Paris, Madrid (heure d’été)), webkitRelativePath: "", size: 49029, type:"image/png"…}
For those that are looking for a solution to this problem, I created an npm package to make it easier to retrieve files using Node's file system and convert them to JS File objects:
https://www.npmjs.com/package/get-file-object-from-local-path
This solves the lack of interoperability between Node's fs file system (which the browser doesn't have access to), and the browser's File object type, which Node cannot create.
3 steps are required:
Get the file data in the Node instance and construct a LocalFileData object from it
Send the created LocalFileData object to the client
Convert the LocalFileData object to a File object in the browser.
// Within node.js
const fileData = new LocalFileData('path/to/file.txt')
// Within browser code
const file = constructFileFromLocalFileData(fileData)
So, I search with File Systems and others possibilities and nothing.
I decide to create my own File object with JSON.
var imagePath = path.join('/images/logo.png', 'logo.png');
if (fs.statSync(imagePath)) {
var bitmap = fs.readFileSync(imagePath);
var bufferImage = new Buffer(bitmap);
Magic = mmm.Magic;
var magic = new Magic(mmm.MAGIC_MIME_TYPE);
magic.detectFile(imagePath, function(err, result) {
if (err) throw err;
datas = [{"buffer": bufferImage, "mimetype": result, "originalname": path.basename(imagePath)}];
var JsonDatas= JSON.parse(JSON.stringify(datas));
log.notice(JsonDatas);
});
}
The output :
{
buffer:
{
type: 'Buffer',
data:
[
255,
216,
255
... 24908 more items,
[length]: 25008
]
},
mimetype: 'image/png',
originalname: 'logo.png'
}
I think is probably not the better solution, but it give me what I want. If you have a better solution, you are welcome.
You can use arrayBuffer (thats what i did to make a downloadable pdf) or createReadStream / createWriteStream under fs(FileSystem objects)
I'm using Dropzone.js for uploading files. Now I want to do some additional validation for some files. But I didn't found a way to get the absolute path of selected file. Please anyone tell me whether there have any way to get the file path.
This is the file array returned by dropzone when we add a file
accepted: true
lastModifiedDate: Wed Dec 17 2014 13:01:03 GMT+0530 (IST)
name: "xxxxxx.pdf"
previewElement: div.dz-preview.dz-file-preview.dz-processing
previewTemplate: div.dz-preview.dz-file-preview.dz-processing
processing: true
size: 407552
status: "uploading"
type: "application/pdf"
upload: ObjectwebkitRelativePath: ""
xhr: XMLHttpRequest
__proto__: File
The full path comes through in the POST data:
Dropzone.options.yourDropzoneID = {
init: function() {
this.on("sending", function(file, xhr, data) {
if(file.fullPath){
data.append("fullPath", file.fullPath);
}
});
}
};