Try this attached sample; a project exported as XML. Start with simple.csp, then select the file upload link. It should upload a file to CachÃ, storing both the filename and MIME type information. This version stores it into a global, but it can be easily adjusted to store into a local file stream.
Then, from simple.csp you can select the either of the file list options. There pretty much the same, the only difference being one uses the traditional syntax for opening objects and the other uses the contemporary.
I've cleaned this sample up for Cachà 5.0.x. You should be able to use it as a guide. Please let me know if you have any questions about it.
Thanks much,
Gregory
--------------000108050409000005050503 Content-Type: text/xml; name="Streams_Globals_CSP.xml" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline; filename="Streams_Globals_CSP.xml"
<?xml version="1.0" encoding="UTF-8"?> <Export generator="Cache" version="9" zv="Cache for Windows NT (Intel) 5.0.9 (Build 5202_1U)" ts="2004-07-14 06:14:38"> <Project name="StreamsGlobalsCSP" LastModified="2004-07-14 06:14:38" HttpServer="http://127.0.0.1"> <Items> <ProjectItem name="Test.FileHolder" type="CLS"/> <ProjectItem name="Test.GetFileG" type="CLS"/> <ProjectItem name="csp/test/streams/FileList.csp" type="CSP"/> <ProjectItem name="csp/test/streams/FileList2.csp" type="CSP"/> <ProjectItem name="csp/test/streams/Simple.csp" type="CSP"/> <ProjectItem name="csp/test/streams/Upload2G.csp" type="CSP"/> </Items> </Project> <Class name="Test.FileHolder"> <Description> Holds any type of binary file.</Description> <ClassType>persistent</ClassType> <Super>%Library.Persistent</Super> <TimeChanged>59506,49057.288861</TimeChanged> <TimeCreated>59129,29056.106</TimeCreated>
<Projection name="MyJava"> <Type>%Projection.Java</Type> <Parameter name="ROOTDIR" value="C:\Cache5\Devuser\java"/> </Projection>
<Property name="ContentType"> <Type>%Library.String</Type> <Final>0</Final> <Calculated>0</Calculated> <Collection/> <MultiDimensional>0</MultiDimensional> <Private>0</Private> <Relationship>0</Relationship> <Required>0</Required> <SqlComputed>0</SqlComputed> <Transient>0</Transient> </Property>
<Property name="FileData"> <Type>%Library.Stream</Type> <Final>0</Final> <Calculated>0</Calculated> <Collection>binarystream</Collection> <MultiDimensional>0</MultiDimensional> <Private>0</Private> <Relationship>0</Relationship> <Required>0</Required> <SqlComputed>0</SqlComputed> <Transient>0</Transient> </Property>
<Property name="FileName"> <Type>%Library.String</Type> <Final>0</Final> <Calculated>0</Calculated> <Collection/> <MultiDimensional>0</MultiDimensional> <Private>0</Private> <Relationship>0</Relationship> <Required>0</Required> <SqlComputed>0</SqlComputed> <Transient>0</Transient> </Property>
<Method name="CopyDocument">
<Description>
This method copies a plain text document into Cache.</Description>
<FormalSpec>physical:%String=""</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
s fcs = ##class(%FileCharacterStream).%New()
s fcs.Filename = physical
d ..FileData.CopyFrom(fcs)
s ..ContentType = "text/plain"
s ..FileName = $RE($E($RE(physical),1,$F($RE(physical),"\")-2))
s fcs = ""
q ..%Save()
]]></Implementation>
</Method>
<Method name="LogicalToFile">
<Description>
Creates a new file from a stored file stored in the database in Global.
This method creates the new file in the Namespace directory (ie, where the namespace
cache.dat is stored).</Description>
<Final>0</Final>
<ClassMethod>1</ClassMethod>
<CodeMode>code</CodeMode>
<FormalSpec>OBJID:%Library.String</FormalSpec>
<Private>0</Private>
<ReturnType>%Library.Status</ReturnType>
<SqlProc>0</SqlProc>
<Implementation><![CDATA[
q:('##class(Test.FileHolder).%ExistsId(OBJID)) "0 - File does not exist!"
s oref = ##class(Test.FileHolder).%OpenId(OBJID)
s file = ##class(%Library.File).%New(oref.FileName)
d file.Open("NWS")
d file.CopyFrom(oref.FileData)
d oref.%Close(),file.%Close()
q 1
]]></Implementation>
</Method><Query name="FileList"> <Description> This query returns a list of files stored in this class.</Description> <Type>%Library.SQLQuery</Type> <SqlQuery>SELECT ID, FileName, ContentType FROM Test.FileHolder ORDER BY FileName</SqlQuery> <Parameter name="CONTAINID" value="1"/> <Parameter name="ROWSPEC" value="ID,FileName:%Library.String,ContentType:%Library.String"/> </Query>
<Method name="GetFileAndSave"> <FormalSpec>dir:%String="",file:%String,type:%String</FormalSpec> <ReturnType>%Library.Status</ReturnType> <Implementation><![CDATA[ q:(dir = "") "0 - Need a valid directory." s dirAndFile = dir_file s tmpstream = ##class(%FileBinaryStream).%New() d tmpstream.FilenameSet(dirAndFile) d ..FileData.CopyFromAndSave(tmpstream) s ..ContentType = type s ..FileName = file s tmpstream = "" q ..%Save() ]]></Implementation> </Method>
<Storage name="Default"> <Type>%Library.CacheStorage</Type> <DataLocation>^Test.FileHolderD</DataLocation> <DefaultData>FileHolderDefaultData</DefaultData> <IdLocation>^Test.FileHolderD</IdLocation> <IndexLocation>^Test.FileHolderI</IndexLocation> <StreamLocation>^Test.FileHolderS</StreamLocation> <Data name="FileHolderDefaultData"> <Structure>listnode</Structure> <Value name="1"> <Value>ContentType</Value> </Value> <Value name="2"> <Value>FileData</Value> </Value> <Value name="3"> <Value>FileName</Value> </Value> <Value name="4"> <Value>%%CLASSNAME</Value> </Value> </Data> </Storage> </Class> <Class name="Test.GetFileG"> <Super>%CSP.Page</Super> <TimeChanged>59625,28387.256296</TimeChanged> <TimeCreated>59129,29056.246</TimeCreated> <ClassDefinitionError>0</ClassDefinitionError>
<Method name="OnPage">
<Final>0</Final>
<ClassMethod>1</ClassMethod>
<CodeMode>code</CodeMode>
<FormalSpec/>
<Private>0</Private>
<ReturnType>%Status</ReturnType>
<SqlProc>0</SqlProc>
<Implementation><![CDATA[
n id,s
s id = %request.Get("OBJID")
if (id = "") {
&html<
<HTML>
<HEAD>
<TITLE>No ID Given</TITLE>
</HEAD>
<BODY>
<P>Please insert a valid id. The URL should look similar to the following:
<PRE>
http://ip.address/some/dir/GetFileG.cls?OBJID=1
</PRE>
</P>
</BODY>
</HTML>
>
q $$$OK
}
s s = ##class(Test.FileHolder).%OpenId(id)
d s.FileData.OutputToDevice()
s s = ""
Quit $$$OK
]]></Implementation>
</Method><Method name="OnPreHTTP">
<Description><![CDATA[
Event handler for <B>PREHTTP</B> event: this is invoked before
the HTTP headers for a CSP page have been sent. All changes to the
<class>%CSP.Response</class> class, such as adding cookies, HTTP headers,
setting the content type etc. must be made from within the OnPreHTTP() method.
Also changes to the state of the CSP application such as changing %session.Preserve,
%session.EndSession or %session.AppTimeout must be made within the OnPreHTTP() method.
Return <B>0</B> to prevent <method>OnPage</method> from being called.]]></Description>
<Final>0</Final>
<ClassMethod>1</ClassMethod>
<CodeMode>code</CodeMode>
<FormalSpec/>
<Private>0</Private>
<ReturnType>%Boolean</ReturnType>
<SqlProc>0</SqlProc>
<Implementation><![CDATA[
n id,s
s id = %request.Get("OBJID")
if (id = "") {
s %response.ContentType="text/html"
q 1
}
s s = ##class(Test.FileHolder).%OpenId(id)
s %response.ContentType=s.ContentType
d %response.SetHeader("Content-Disposition","inline; filename="""_s.FileName_"""")
s %response.Expires=10
// deprecated - d s.%Close()
s s = ""
q 1
]]></Implementation>
</Method>
</Class>
<CSP name="streams/FileList.csp" application="/csp/test/" default="1">
<![CDATA[<html>
<head>
<title>File List</title>
</head>
<body>
<p>Below are the files currently stored in this global:</p>
<hr>
<csp:query classname="Test.FileHolder" name="query" queryname="FileList">
<table cellspacing="5" cellpadding="7%">
<tr>
<th>#(query.GetColumnHeader(2))#</th>
<th>#(query.GetColumnHeader(3))#</th>
<th>Size (Bytes)</th>
</tr>
<csp:while condition='query.Next()'>
<tr>
<td><a
href="Test.GetFileG.cls?OBJID=#(query.Get("ID"))#">#(query.Get("FileName"))#</a></td>
<td>#(query.Get("ContentType"))#</td>
<td>#(##class(Test.FileHolder).%OpenId(query.Get("ID")).FileData.Size)#</td>
</tr>
</csp:while>
</table>
<hr>
<p><a href="Simple.csp">Return to File Upload Menu page.</a></p>
</body>
</html>
]]></CSP>
<CSP name="streams/FileList2.csp" application="/csp/test/" default="1">
<![CDATA[<html>
<head>
<title>File List</title>
</head><body>
<p>Below are the files currently stored in this global:</p>
<hr>
<csp:query classname="Test.FileHolder" name="query" queryname="FileList">
<table cellspacing="5" cellpadding="7%">
<tr>
<th>#(query.GetColumnHeader(2))#</th>
<th>#(query.GetColumnHeader(3))#</th>
<th>Size (Bytes)</th>
</tr>
<csp:while condition='query.Next()'>
<tr>
<td><a
href="Test.GetFileG.cls?OBJID=#(query.Get("ID"))#">#(query.Get("FileName"))#</a></td>
<td>#(query.Get("ContentType"))#</td>
<td>#($system.OBJ.OpenId("Test.FileHolder",query.Get("ID")).FileData.Size)#</td>
</tr>
</csp:while>
</table>
<hr>
<p><a href="Simple.csp">Return to File Upload Menu page.</a></p>
</body>
</html>
]]></CSP>
<CSP name="streams/Simple.csp" application="/csp/test/" default="1">
<![CDATA[<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html>
<head>
<title>File Upload Menu - Simple</title>
</head><body> <h2>File Upload Menu - Simple</h2> <p><a href="Upload2G.csp">Upload a File to a Global</a> <p><a href="FileList.csp">List of Uploaded Files (uses ##class(...).%OpenId(...)</a> <p><a href="FileList2.csp">List of Uploaded Files (uses $system.OBJ.OpenId(...))</a>
</body> </html> ]]></CSP> <CSP name="streams/Upload2G.csp" application="/csp/test/" default="1"> <![CDATA[<!--Demo of how to upload files via a stream to a Global.-->
<html> <head>
<title>File Upload To Global</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#FFFFFF">
<form enctype="multipart/form-data" method=post action="Upload2G.csp">
<table>
<tr>
<td id="Org3">
Select a file to upload here: </td></tr>
<tr>
<td id="Org3">
<input type="file" size="30" name="FileStream">
</td>
</tr>
<tr>
<td id="Org3">
<input type=submit value="Upload file">
<input type=HIDDEN name="PID" value=#(%request.Get("PID"))#>
<!-- As form is submitted to this page look to see if we have the stream in the %request
object -->
<csp:IF CONDITION=(%request.IsDefinedMimeData("FileStream"))>
<server>
New type,store,filename,filedata
Set store=##class(Test.FileHolder).%New(),done=0
set filename=%request.GetMimeData("FileStream").FileName
set type=%request.GetMimeData("FileStream").ContentType
if (filename["\") {
set len=$L(filename,"\")
set name=$P(filename,"\",len)
set done=1
}
if (filename["/") {
set len=$L(filename,"/")
set name=$P(filename,"/",len)
set done=1
}
if 'done {
set name=filename
}
s store.FileName = name
s store.ContentType = type
set filedata = store.FileData.CopyFromAndSave(%request.GetMimeData("FileStream"))
s sc = store.%Save()
</server>
<tr colspan="2">
<td id="Org3"> File has been loaded to the Cachà server.</td>
</tr>
<tr>
<td>Save Code: #(sc)#</td>
</tr>
</csp:IF><tr><td id="Org5"> Please be patient - the upload process is not fast and is dependent on your network connection as well.</td></tr> <tr><td id=Org5><a href="Simple.csp">Return to File Upload Menu page.</a></td></tr> </table> </form> </body> </html>]]></CSP> <Checksum value="2842991922"/> </Export>
--------------000108050409000005050503--
