How do I read in FILE contents in QML? - qt

I just need something similar to Fstream to read file IO in QML. Why is there no file IO?

If your file is plain text you can use XMLHttpRequest. For example:
var xhr = new XMLHttpRequest;
xhr.open("GET", "mydir/myfile.txt");
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
var response = xhr.responseText;
// use file contents as required
}
};
xhr.send();

I know this is old question but you might be still interested in answer.
Here it is: Reading a line from a .txt or .csv file in qml (Qt Quick)
In short, you have here explained how to read files in QML: http://www.developer.nokia.com/Community/Wiki/Reading_and_writing_files_in_QML
All you need is to extend QML with C++.

QML has no built-in file I/O. But - judging from the tone of your post - you already knew that.
How do I read in FILE contents in QML?
You can extend QML's functionalities using C++.
The Getting Started Programming with QML tutorial from the Qt Reference Documentation shows you how to build a text editor. This includes file I/O using C++.
Why is there no file I/O?
Because QML is based on JavaScript, and JavaScript has no built-in file I/O either.
QML is designed as an (easy) way to build a user interface. You need an actual program to do the rest.

There is built-in file I/O available for QML with the Felgo SDK (formerly V-Play) FileUtils. It works cross-platform on desktop, iOS and Android. More info and examples are also in the latest blog post.
It looks like this:
var documentsData = fileUtils.readFile("subfolder/file.json")

function readConfigFile() {
var xhr = new XMLHttpRequest;
var configaddress = "File:///" + root + "/webconfig.txt" //root = "c:/folder/file.ini";
console.log(configaddress);
xhr.open("GET", configaddress);
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
var response = xhr.responseText;
var js = JSON.parse(response)
if (js.address != "") {
service_address = js.address
}
// use file contents as required
}
};
xhr.send();
}

What do you want to read the file for?... if its simple data.. then you are probably better off using QML Offline storage API. Look for that section here.
If you want to deploy a db with your application read this conversation.
If you really want to read the file still, learn C++ and expose your code to QML. That, then, is beyond the scope of my answer.

Related

Xamarin - CachedImage - Access the downloaded file

I am using the CachedImage component of ffimageloading. I have a kind of gallery with a carousel view.
All the images are loaded through an internet URL, they are not local images. I would like to add the image sharing function. But I don't want to download the file again, I would like to know if there is a way to access the file that the CachedImage component already downloaded to be able to reuse it in the share function.
try using MD5Helper
var path = ImageService.Instance.Config.MD5Helper.MD5("https://yourfileUrlOrKey")'
Thanks Jason
I share with you how part of my code is:
var key = ImageService.Instance.Config.MD5Helper.MD5("https://yourfileUrlOrKey");
var imagePath = await ImageService.Instance.Config.DiskCache.GetFilePathAsync(key);
var tempFile = Path.Combine(Path.GetTempPath(), "test.jpg");
if (File.Exists(tempFile))
{
File.Delete(tempFile);
}
File.Copy(imagePath, tempFile);
await Share.RequestAsync(new ShareFileRequest
{
Title = "Test",
File = new ShareFile(tempFile)
});
The temporary file I believe, since the cached file has no extension and the applications do not recognize the type.

Read (audio) file from subfolder in AndroidAssets in Xamarin.Forms

I try to eneable audio in my Xamarin.Forms application. I want to have the audio files in a Subfolderof the Assetsfolder like this Assets/Subfolder/Audio.mp3
I have found a plugin SimpleAudioPlayer which provide an example.
The following code works like provided.
var player = Plugin.SimpleAudioPlayer.CrossSimpleAudioPlayer.Current;
player.Load("Audio.mp3");
Now I want to place the audio file in a subfolder and I tried to call
player.Load("Subfolder/Audio.mp3");
But I get an Java.IO.FileNotFoundException
I looked then into the implementation of the Load function and I fould the following code
public bool Load(string fileName)
{
player.Reset();
AssetFileDescriptor afd = Android.App.Application.Context.Assets.OpenFd(fileName);
player?.SetDataSource(afd.FileDescriptor, afd.StartOffset, afd.Length);
return PreparePlayer();
}
where the filename is pasted to the Assets.OpenFd() function. which returns an AndroidFileDesriptor
The documentation does not really provide any information from Microsoft and from the Android site.
My questions are
How can I receive the file from the subfolder in Android Assets?
What can I paste into the Assets.OpenFd() function (subfolders etc)?
I would appreciate any advice, since after a long time trying to resolve it I don't really have an idea.
According to the docs of the package, you won't be able to do just that because you have to use player.Load(GetStreamFromFile("mysound.wav")); where GetStreamFromFile is basically
Stream GetStreamFromFile(string filename)
{
var assembly = typeof(App).GetTypeInfo().Assembly;
var stream = assembly.GetManifestResourceStream("App." + filename);
// Obviously App in the line above should be replaced with your app
return stream;
}
And secondly you have to player.Load(GetStreamFromFile("Subfolder.mysound.wav")); where Subfolder is the name of your subfolder.

how to Preview the video file that user wants to upload on the website (PHP, FiileAPI JS)

I mean, when a user chooses the video file from their system, have the web-page already show them the files they want to upload.
I'm already using image file to preview using FileAPI JS. The same I want to do with FileAPI JS for video file.
(So, It must be work within my client side)
Thanks & answers are appreciated :)
You can either use FileReader or createObjectURL. They'll both get the job done, but FileReader has slightly broader support in browsers.
createObjectURL will run synchronously and return a Blob URL, a short string referencing the file in memory. and you can free it up immediately after you're done using it.
FileReader will run asynchronously, requiring a callback, providing a Data URI, a much longer string representing the whole file. This can be very big and will be freed from memory in Javascript garbage collection.
Here's an example that first tries createObjectURL and falls back to FileReader. (Please provide your own error checking, etc.)
var video = document.getElementById('video'),
input = document.getElementById('input');
input.addEventListener('change', function (evt) {
var reader = new window.FileReader(),
file = evt.target.files[0],
url;
reader = window.URL || window.webKitURL;
if (reader && reader.createObjectURL) {
url = reader.createObjectURL(file);
video.src = url;
reader.revokeObjectURL(url); //free up memory
return;
}
if (!window.FileReader) {
console.log('Sorry, not so much');
return;
}
reader = new window.FileReader();
reader.onload = function(evt) {
video.src = evt.target.result;
};
reader.readAsDataURL(file);
}, false);
Working example here: http://jsbin.com/isodes/1/edit
Mozilla has a more detailed article with instructions on how to upload once you've got your file.
IE10 supports both, but IE9 supports neither, so you'll have to fall back to a regular form upload without a preview.

FileReference.load() does not as excepted

I used Flash player 10, and Flex SDK 3.4. The code as followings:
// Following comes callbacks
function imageLoadOpenCallback(evt:Event):void
{
trace("in--open");
}
function imageLoadCompleteCallback(evt:Event):void
{
trace("in--load");
var fr:FileReference = evt.target as FileReference;
trace(fr.data);
}
function imageLoadErrorCallback(evt:IOErrorEvent):void
{
trace("in--ioerror");
}
function imageSelectCancelCallback(evt:Event):void
{
trace("in cancel");
}
function imageSelectCallback(evt:Event):void
{
trace("in -- select");
for (var i:int=0; i<frl.fileList.length; i++)
{
frl.fileList[i].addEventListener(Event.OPEN, imageLoadOpenCallback);
frl.fileList[i].addEventListener(Event.COMPLETE, imageLoadCompleteCallback);
frl.fileList[i].addEventListener(IOErrorEvent.IO_ERROR, imageLoadErrorCallback);
frl.fileList[i].load();
trace(frl.fileList[i]);
trace(frl.fileList[i].creationDate);
trace(frl.fileList[i].creator);
trace(frl.fileList[i].data);
trace(frl.fileList[i].name);
}
}
// Following comes UI handlers
function onAddPictures():void
{
var imageFilter:FileFilter = new FileFilter("Images", "*.jpg;*.png");
frl.addEventListener(Event.SELECT, imageSelectCallback);
frl.addEventListener(Event.CANCEL, imageSelectCancelCallback);
frl.browse([imageFilter]);
}
Only the imageSelectCancelCallback handler get called when I select some files in the dialog. But no load/open/io_error handler get called at all. I have Google some code example, in which it used FileReference instead of FileReferenceList. I don't know the reason, could you please help me?
In Air the fileReference objects in fileReferenceList do not fire the complete event when doing fileList[i].load(). In a Flex project it works fine. Adobe has not responded to bug reports on this appropriately.
Make sure in your compiler settings for flex, that you have at least 10.0.0 for "Use a specific version".
The main reason to use FileReferenceList instead of FileReference would be if you need to upload multiple files at once. If you only want to allow uploading one file at once, simply use FileReference.
Some clarification: imageSelectCallback(), and NOT imageSelectCancelCallback(), should get called when you select some files in the file browser AND click OK. imageSelectCancelCallback() is only called when you click Cancel.
Other than that, I never used the load() API, but I did use the upload(URLRequest) API. I am not sure what's your use case, but if you need to upload an image to a server, you should use the upload() method.
Speaking of upload events, I experienced some reliability issues when listening to Event.COMPLETE events, so I actually got better results listening to DataEvent.UPLOAD_COMPLETE_DATA.

how to download files to a default dir without poping an option window in Flex/Air?

I'm writing a app with Flex/air,and i need a function that downloading files to the default dir without a pop-up window.i tried to use ftp instead of http but found it's not supported by air.how can i solve this problem?
This should be possible in AIR. I don't know if there's a direct API approach, but you should be able to load the bytes into memory and then flush them into a file. In pseudo-pseudo-code using File and FileStream:
// get the bytes
var loader:URLLoader = new URLLoader();
loader.load("http://www.stackoverflow.com");
...
var bytes:ByteArray = loader.data;
// get the file in the correct location
var f:File = File.documentsDirectory.resolvePath("myfile.txt");
// write the file
var fs:FileStream = new FileStream(f, FileMode.WRITE);
fs.writeBytes(bytes);
fs.close();
There are a few examples out there to look at.
None of this is possible in Flash Player because of the security limits #viatropos suggests.
I don't think you can do that as it's a Security violation. The user must be prompted with a download window so they can choose the directory. I think the thinking goes "if you don't prompt the user, then a Flash/Flex app could download a bunch of junk to their computer without their permission", and that would make adobe look bad :/. I wish you could though.
You can, however, download it using a server side script without asking the user for permission. I do that with ruby to accomplish what you're describing.
Hope that helps,
Lance
You can but only air version because you have to use FileStream
var ff:File = File.desktopDirectory.resolvePath("sample.dwg");
var u:String = obj_l.d1.selectedItem.data + "" + obj_l.d2.selectedItem.label;
var ll3:URLLoader = new URLLoader ();
u = GETURL() + u;
rr.url = u;
//ff.download(rr);
ll3.dataFormat = URLLoaderDataFormat.BINARY;
ll3.load(rr);
ll3.addEventListener(Event.COMPLETE , function (e:Event):void {
var stream:FileStream = new FileStream ();
stream.open(ff,FileMode.WRITE);
stream.writeBytes(ll3.data);
});

Resources