A variety of files (pdf, images, etc.) are stored in a ntext field on a MS SQL Server. I am not sure what type is in this field, other than it shows question marks and undefined characters, I am assuming they are binary type.
The script is supposed to iterate through the rows and extract and save these files to a temp directory. "filename" and "contenttype" are given, and "data" is whatever is in the ntext field.
I have tried several solutions:
1) data.SaveToFile "/temp/"&filename, 2
Error: Object required: '????????????????????'
???
2) File.WriteAllBytes "/temp/"&开发者_C百科amp;filename, data
Error: Object required: 'File'
I have no idea how to import this, or the Server for MapPath. (Cue: what a noob!)
3)
Const adTypeBinary = 1
Const adSaveCreateOverWrite = 2
Dim BinaryStream
Set BinaryStream = CreateObject("ADODB.Stream")
BinaryStream.Type = adTypeBinary
BinaryStream.Open
BinaryStream.Write data
BinaryStream.SaveToFile "C:\temp\" & filename, adSaveCreateOverWrite
Error: Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another.
4)
Response.ContentType = contenttype
Response.AddHeader "content-disposition","attachment;" & filename
Response.BinaryWrite data
response.end
This works, but the file should be saving to the server instead of popping up save-as dialog. I am not sure if there is a way to save the response to file.
Thanks for shedding light on any of these problems!
Since the column is NTEXT, all SqlClient objects are going to interpret it as an unicode string, and this will cause all sort of problems. You should change the column to varbinary(max).
Once you have the column as a true binary, appropriate for a file, you can read the column stream from SqlClient and write the stream into the response (skipping the intermediate temp file):
void StreamFileToResponse(int id, SqlConnection connection) {
SqlCommand cmd = new SqlCommand(@"select data from table where id = @id", connection);
cmd.Paramaters.AddWithValue("@id", id);
using(SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.SequentialAccess) {
while (rdr.Read()) {
Stream data = rdr.GetSqlBytes(0).Stream;
byte[] buffer = new byte[4096];
while(int read = data.Read(buffer, 0, 4096)) {
Response.BinaryWrite(buffer, 0, read);
}
}
}
The SequentialAcccess flag passed to ExecuteReader is critical, otherwise the reader will read the entire file in memory first.
精彩评论