Have built a very useful document management add in to my solution that performs perfectly on development system streaming files to and from the server without issue.
Files are save into a server folder using the standard fileserver service plugin and i store only the link to the file in the db. Files are stored in the server as a:
“_.extension”
Again this all works perfectly with the development system and I can see the files stored in the server folder. Am streaming the files back to the client with the following method:
var vID = rowData[5];
var vMaster = rowData[0];
var vFilename = rowData[2];
//returns filename stripped of extension
var retval = utils.stringReplace(vFilename, vFiletype,'');
//add _ID and extension
var name = "/" + retval + "_" + vID + vFiletype;
var index = vFilename.lastIndexOf('.');
var prefix = vFilename.substr(0,index);
var suffix = vFilename.substr(index);
var tempFile = plugins.file.createTempFile(prefix, suffix);
//create a read record
if (tempFile)
{
var monitor = plugins.file.streamFilesFromServer(tempFile, name);
//create read record
var vFs = databaseManager.getFoundSet('documents', 'document_reads');
var r_id = vFs.newRecord();
var record = vFs.getRecord(r_id);
record.document_master_id = vMaster;
record.document_version_id = vID;
databaseManager.saveData();
}
//then open it
if(utils.stringMiddle(application.getOSName(),1,7) == "Windows")
{
application.executeProgramInBackground('rundll32', 'url.dll,FileProtocolHandler', tempFile)
}
else if (utils.stringLeftWords(application.getOSName(), 1) == "Mac")
{
application.executeProgram('open', tempFile);
}
With a client server model I am having issues streaming back large (>700KB) .jpg and .pdf files. Am getting an error in the default application when it tries to open the files, that thinks the files are in use (screenshot attached).
This does not happen in word or excel files (these can be any size it seems) and it doesn’t appear to be an issue with smaller .pdf or .jpg files.
Is this a known issue or am I missing something in the code?
plugins.file.streamFilesFromServer is doing that in a seperate thread!, and uses normally a callback method, when it is finished!
so your code runs directly after calling the streaming, so it can be the case, that the streaming is still not ready yet!!
so your method, should stop, right after: plugins.file.streamFilesFromServer
and than, your read-record creation and open the file, should be in a separate callback method.
I think locally works so well, because than it is very quick!!
look at the sample code for plugins.file.streamFilesFromServer
var dir = plugins.file.showDirectorySelectDialog();
if (dir) {
var list = plugins.file.getRemoteFolderContents('/images/user1/', null, 1);
if (list) {
var monitor = plugins.file.streamFilesFromServer(dir, list, callbackFunction);
}
}
There are 2 arguments passed back from the callbackFunction (an integer and a number with a single decimal point). Do you know what do they represent and how to use these in the determining the progress of the callbackFunction?
rodneysieb:
There are 2 arguments passed back from the callbackFunction (an integer and a number with a single decimal point). Do you know what do they represent and how to use these in the determining the progress of the callbackFunction?
The arguments should be a JSFile and an exception. One or the other will be null, so your callbackFunction should look like:
/**
* @param {JSFile} file
* @param {Exception} exception
*/
function callbackFunction(file, exception) {
if (exception) {
// do something to handle this here
application.output(exception);
} else {
// you should have a valid JSFile here
application.output(file);
}
}
If you want to be notified of progress, you should use the monitor object that is returned to configure a progressCallback, so do this:
var monitor = plugins.file.streamFilesFromServer(dir, list, callbackFunction);
monitor.setProgressCallBack(progressCallbackFunction, 2);
// no need to hold onto the monitor object, your progressCallbackFunction will receive it again every 2 seconds!
Then your progressCallbackFunction will receive an updated JSProgressMonitor, like so:
/**
* @param {JSProgressMonitor}
*/
function progressCallbackFunction(monitor) {
// use the JSProgressMonitor methods here to know where the transfer is at.
}
I did a sample solution (complete with a basic progress window) to demonstrate the streaming capabilities of the file plugin, check out the servoy_sample_StreamFiles.servoy file at Files - Servoy-Stuff Tutorials - ServoyForge, this should give you a good idea of how this all work.