Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 SQL Server Development (2000)
 Download file to client w/out write to server hd

Author  Topic 

cfukai
Starting Member

4 Posts

Posted - 2003-12-17 : 20:11:29
Okay, so I am storing binary files in my SQL Server database (in an image field). I know, I know... "Bad developer!!! Bad, bad developer!!" I'll just say that right now it's what I want to do and that's not going to change (until I eat crow and end up storing on the file system anyway!).

But let's move on assuming everything will stay in the database. I have an ASP (Classic ASP, not ASP.Net) application that interfaces this database and should allow clients to download the files stored in the database to their machines via a web browser.

I guess the easiest way would be to use an ADO stream to read the file out of the database and write it to some temp location on the server's hard drive, and then use Response.BinaryWrite to feed that file to the client. I would like to avoid having to write to the server's hard drive and just read the file from the server's memory (stream) directly to the client, where it will then be written to their hard drive.

Any ideas? :)

Many thanks in advance for input anyone could provide.

Colin

Merkin
Funky Drop Bear Fearing SQL Dude!

4970 Posts

Posted - 2003-12-17 : 20:23:50
You can Response.BinaryWrite directly to the client (actually you might need one of the Soft Artisan components to do this). If you set the http headers properly the client will be presented with a save dialog.



Damian
Go to Top of Page

cfukai
Starting Member

4 Posts

Posted - 2003-12-17 : 20:47:06
quote:
Originally posted by Merkin

You can Response.BinaryWrite directly to the client (actually you might need one of the Soft Artisan components to do this). If you set the http headers properly the client will be presented with a save dialog.



I am not using any SA component right now, but here are my headers:

Response.ContentType="application/x-msdownload"
Response.AddHeader "Content-Disposition", "attachment; filename=test.dat;"
Response.Buffer = true

The file name "test.dat" is just some dummy name I put in there. I get a "Save As" dialog prompt, but the name of the file is the asp page (with querystring). When I click "Save" the file is not downloaded, I just get an error message from IE that says:

Internet Explorer cannot download test.asp from localhost. IE was not able to open this Internet site. The requested site is either unavailable or cannot be found. Please try again later.

Am I setting up my headers correctly? When I do my binary write it basically looks like this:

set st = Server.CreateObject("ADODB.Stream")
st.Type = adTypeBinary
st.Open
st.Write rs("FileData").Value
Response.BinaryWrite st.Read

Thanks!
Go to Top of Page

cfukai
Starting Member

4 Posts

Posted - 2003-12-17 : 22:12:28
Okay, after playing around some more I believe I've pinpointed my problem down to the stream. Here's what I did.

Instead of using BinaryWrite to save to the client I just wrote the file from the stream directly to the server hard drive, just to ensure that the binary contents of the stream were OK. That was no problem. The file written to the server worked fine.

Next, I re-implemented BinaryWrite but instead of reading the file into the stream from the database I read it from a copy of the file on the server's hard drive. Now that saved to the client just fine, with the proper "Save As" prompt and everything.

So I guess there's something wrong with the binary data getting read from the database, into the stream, and then sent to the client using BinaryWrite. I'll investigate more, but anyone's comments are always appreciated :)
Go to Top of Page

cfukai
Starting Member

4 Posts

Posted - 2003-12-17 : 22:58:29
Okey doh, I think I solved my problem. I ended up throwing out all the ADO Stream code and just BinaryWrite'ing the data from the recordset directly. So, in my code - after reading the file from the database into a recordset - here is what I did:

Response.ContentType="application/x-msdownload" 'Tell the browser the data is for download
Response.AddHeader "Content-Disposition", "attachment; filename=" & rs("FileName") & ";" 'Tell the browser to associate a file name with the data
Response.Buffer = true
Response.BinaryWrite rs("FileData")

Well, I can't say it doesn't make sense. I guess I was just trying to do things too hard ;) Of course, as I think more and more about my app I am starting to talk myself in to saving the files to disk to begin with :) I've done apps using that approach before, and the only things I really didn't like were:

1. Coming up with a directory scheme to segregate a user's files from everyone else, but clean enough that I don't have levels and levels of folders to wade through.

2. Cleaning out the garbage from aborted uploads (when you're not uploading directly to memory).

Really, these are just little nags more than they're real problems. I guess I just like centralization. That's why I was hoping to store all files in the database. I think that's fine when the files are going to be relatively small in size, but once you start getting above a couple megs or so then performance really starts to kill you.

Thanks!
Go to Top of Page
   

- Advertisement -