File Upload

550 views
Skip to first unread message

UtsaviG

unread,
Aug 25, 2009, 11:50:16 PM8/25/09
to InterSystems: Zen Community
Hello Everyone,

In one of class used in our system we are allowing User to upload file
from his/her machine. What we actually do is allow User to select any
file from his machine and when he clicks on upload we do not store
that on server we just read file content and store it in session
variable and then Use that Variable for further processiong.

Now to do this we are using a CSP Page same as upload.csp provided in
Samples by InterSystems which uses %request.MimeData("file").Read().
But I noticed that it does not upload files which are of more than
30KB in size. I mean I tried to upload a file of 60KB but it just read
half of the records from file. I tested upload.csp availbale in
Samples Namespace but it also does the same thing.

I tried to find out if that is a limitation of %request object but
couldn't find anything in Documentation.
Has anyone come across this problem before? Is there any way to
increase file size limit or any other way to do this functionality?

Any help would be highly appreciated.

Thanks,
Utsavi

Benjamin Spead

unread,
Aug 26, 2009, 1:02:15 AM8/26/09
to intersys...@googlegroups.com
My guess is that the code you are using is trying to store the file in a %String global, which will be maxed out when it reaches 32K. You will need to have a Stream object (filestream or gloablstream) receive the upload to prevent it from being truncated.

I am afraid I do not have an example handy - perhaps someone else does?

UtsaviG

unread,
Aug 26, 2009, 1:29:48 AM8/26/09
to InterSystems: Zen Community
Thanks Benjamin.

But problem is with Read() Method of %request Object i.e
%request.MimeData("FileUpload",1).Read() only reads data upto 32k.

I do not know how can we upload file from Client to Server using
filestream. I think for filestream we need to specify path for file
but in case of web system client will try to upload file from his
machine but program runs on Server so if I specify path of file it
tries to find that file on Server and fails as it does not find that
file on server.

Do you any example of how to upload file from Client to Server?

Regards,
Utsavi



On Aug 26, 3:02 pm, Benjamin Spead <Benjamin.Sp...@intersystems.com>
wrote:
> Utsavi- Hide quoted text -
>
> - Show quoted text -

Benjamin Spead

unread,
Aug 26, 2009, 1:37:19 AM8/26/09
to intersys...@googlegroups.com
Utsavi,
You are right ... looking at the docs, the MimeType property of the %CSP.Request class is in fact a string:

. property MimeData as %CacheString [ MultiDimensional ];

This means you will need to use a different mechanism for the upload. I am afraid I do not have such an example.

But did you look at the <fileUpload> component in Zen?

http://docs.intersystems.com/cache20091/csp/docbook/DocBook.UI.Page.cls?KEY=GZCP_controls#GZCP_forms_fileUpload

Shouldn't this work for you?

Derek Day

unread,
Aug 26, 2009, 5:00:04 AM8/26/09
to intersys...@googlegroups.com
Does /csp/samples/upload.csp help?

You might try using the CopyFrom() method instead of Read() which does indeed handle data in 32k chunks by default.

Derek Day

unread,
Aug 26, 2009, 5:01:14 AM8/26/09
to intersys...@googlegroups.com
Of course file upload is useful for Zen Forms because it encapsulates the details of Zen based form submissions!

Neerav Verma

unread,
Aug 26, 2009, 11:20:54 AM8/26/09
to intersys...@googlegroups.com
Just a suggestion - Intersystems should take these kind of common situations as examples and add to its Samples library which I think is very helpful .

Unlike other technologies, the only resources which we have access to once we get stuck is Samples, this forum and WRC of course (which should be our last option as they are already overwhelmed with issues) 


Thank You,

Neerav Verma
http://www.linkedin.com/in/vneerav
------------------------------------------------------
It's natural law - Objects in motion tend to stay in motion


------------------------------------------------------------------------------
"This message and any attachments are solely for the intended recipient and may contain confidential or privileged information. If you are not the intended recipient, any disclosure, copying, use, or distribution of the information included in this message and any attachments is prohibited. If you have received this communication in error, please notify us by reply e-mail and immediately and permanently delete this message and any attachments. Thank you."

-------------------------------------------------------------------------------

UtsaviG

unread,
Aug 26, 2009, 8:27:11 PM8/26/09
to InterSystems: Zen Community
Hi Everyone,

Thanks for your help.

Hi Derek,

How do I use CopyFrom Method. Its not method of %request object. I
tried somthing like this

set file = ##class(%GlobalCharacterStream).%New()
d file.CopyFrom(%request.GetMimeData("FileStream")) //.GetMimeData
("FileStream",1).Read()
s i = 1
while 'file.AtEnd
{
Set data = file.ReadLine()
set ^tmp(i) = data
s i = i + 1
}

This works but also does not get all data. I tried to upload file with
60K size using this code and it didn't read last 8 to 10 lines so
looks like this GteMimeData has also got some size limit.
Can you please give me some more idea on how to use CopyFrom Method?

Thanks,
Utsavi


On Aug 26, 7:00 pm, Derek Day <Derek....@intersystems.com> wrote:
> Does /csp/samples/upload.csp help?
>
> You might try using the CopyFrom() method instead of Read() which does indeed handle data in 32k chunks by default.
>
>
>
> -----Original Message-----
> From: "Benjamin Spead" <Benjamin.Sp...@intersystems.com>
> To: "intersys...@googlegroups.com" <intersys...@googlegroups.com>
> Sent: 8/26/2009 1:37 AM
> Subject: [InterSystems-Zen] Re: File Upload
>
> Utsavi,
> You are right ... looking at the docs, the MimeType property of the %CSP.Request class is in fact a string:
>
> . property MimeData  as %CacheString [ MultiDimensional ];
>
> This means you will need to use a different mechanism for the upload.  I am afraid I do not have such an example.
>
> But did you look at the <fileUpload> component in Zen?
>
> http://docs.intersystems.com/cache20091/csp/docbook/DocBook.UI.Page.c...
> > - Show quoted text -- Hide quoted text -

UtsaviG

unread,
Aug 26, 2009, 8:47:47 PM8/26/09
to InterSystems: Zen Community

Hi Benjamin,

Yes I had looked at fileupload component but as far as I have
understood it is only useful if I want to create my own upload window.
And it gives you option to select files residing on server. But if I
select file from client again same issue comes into picture how do I
upload it to server or read its content?

I cannot find anything in Documentation.. I think InterSystem should
improve CACHE documentation I can never find anything there. :(

Thanks,
Utsavi

On Aug 26, 3:37 pm, Benjamin Spead <Benjamin.Sp...@intersystems.com>
wrote:
> Utsavi,
> You are right ... looking at the docs, the MimeType property of the %CSP.Request class is in fact a string:
>
> . property MimeData  as %CacheString [ MultiDimensional ];
>
> This means you will need to use a different mechanism for the upload.  I am afraid I do not have such an example.
>
> But did you look at the <fileUpload> component in Zen?
>
> http://docs.intersystems.com/cache20091/csp/docbook/DocBook.UI.Page.c...
> > - Show quoted text -- Hide quoted text -

Vlado

unread,
Aug 27, 2009, 12:20:59 AM8/27/09
to InterSystems: Zen Community
Hi Utsavi,

See if this can help you something:
Class VICS.FileUpload Extends %ZEN.Component.page
{

/// Class name of application this page belongs to.
Parameter APPLICATION;

/// Displayed name of this page.
Parameter PAGENAME = "FileUpload";

/// Domain used for localization.
Parameter DOMAIN;

/// This XML block defines the contents of this page.
XData Contents [ XMLNamespace = "http://www.intersystems.com/zen" ]
{
<page xmlns="http://www.intersystems.com/zen" title="">
<form id="frmUpload" enctype="multipart/form-data">
<fileUpload id="fileUpload" name="fileUpload" label="File to upload:
"/>
<submit caption="Upload" action="save" id="Submit"/>
</form>
</page>
}

/// This callback is called when a form on this page is submitted.
/// <var>pSubmit</var> is a <class>%ZEN.Submit</class> object
/// containing details of the form submit.<br>
/// Subclasses override this method.
ClassMethod %OnSubmit(pSubmit As %ZEN.Submit) As %Status
{

kill ^TestLog
set tSC=$$$OK
if (pSubmit.%Action = "save")
{
if (%request.IsDefinedMimeData("$V_fileUpload"))
{
set mimeData = %request.GetMimeData
("$V_fileUpload")
Set file=##class(%File).%New("C:\temp\test")
Do file.Open("WSN")
do file.CopyFrom(mimeData)
set tSC = file.%Save()
}
}
Quit tSC
}

/// This callback is called at the end of the HTML HEAD section of the
page.<br>
/// (default implementation is a simple expression).
Method %OnDrawHTMLHead() As %Status
{

w "<meta http-equiv=""Content-Type"" content=""text/html;
charset=GB18030"">"
Q $$$OK
}

}


Actually it copies 1 file from 1 directory to another directory
(outside of Cache).
And probably will copy from client to server and conversely.
You should change the path where the file will be copied here:
Set file=##class(%File).%New("C:\temp\test")

UtsaviG

unread,
Aug 27, 2009, 9:39:38 PM8/27/09
to InterSystems: Zen Community
Hi Everyone,

Thanks very much for all your help.

Finally I fixed my problem. Just wanted to let you know so it might be
helpful to someone in future.

I used csp page to upload file from Client to server and used that CSP
page in ZEN page with Iframe component and then read that file from
server and kill it once all records have been read from file.

Here is the code how I did it

UPLOAD.CSP //This copies uploaded file and saves it to server
----------------------------------

<body>
<form enctype="multipart/form-data" method="post"
action="uploadMarc21.csp">
<input type=file size=30 name=FileStream><input type="submit"
value="Upload file">
</form>

<csp:if condition='($data(%request.MimeData("FileStream",1)))'>
<script language="Cache" runat="server">
Set fileName = ..EscapeHTML(%request.MimeData("FileStream",
1).FileName)
Set ext = $p(fileName,".",$l(fileName,"."))
if (ext="mrc") {

s newfile=##class(%Stream.FileBinary).%New()
s newfile.Filename= "C:\TEMP\T"_$i(^UNIQUE)
s sc=newfile.CopyFromAndSave(%request.MimeData("FileStream",1))

s %session.Data("FileName")=newfile.Filename
write "Submitted file: <b>"_ ..EscapeHTML(%request.MimeData
("FileStream",1).FileName)_"</b>"
}
else
{
write "Only text files (.mrc) are allowed",!
}
</script>
</csp:if>

</body>

METHOD IN ZEN PAGE WHICH READS FILE FROM SERVER
----------------------------------------------------------------------------------------------------

ClassMethod ImportMarc21() [ ZenMethod ]
{
s fileName = $g(%session.Data("FileName"))

/* CODE TO READ FILE FROM SERVER */
s file = ##class(%FileCharacterStream).%New()
d file.TranslateTableSet("UTF8")
s file.LineTerminator=$c(29)
set ok=file.LinkToFile(fileName)

while 'file.AtEnd
{
s data = file.ReadLine()
if data '= ""
{
s line = data_$C(29)
s P3 = $$marcup^VLMARCL(line,0,0,0,0)
}
}
/*This clear command clears permanent storage of stream i.e. it
deletes the file*/
d file.Clear(1)

s %session.Data("FileName") = ""
q
}

Thanks and Regards,
Utsavi

Derek Day

unread,
Aug 28, 2009, 11:44:59 AM8/28/09
to intersys...@googlegroups.com
Thanks for letting us know!

I like that approach because it allows for the possibility of
asynchronously uploading the file, while the user fills in the rest of
the form. Its one of the few things that I like about Iframes -- though
current browsers are starting to support uploading of files (and
previewing) via XMLHttpRequest!

~Derek

UtsaviG wrote (8/27/09 9:39 PM):
Reply all
Reply to author
Forward
0 new messages