I have a stream object in which I have some document, I know what document is it, how can I open that document without saving it into a file physically. So I want to directlly open the document from stream itself without saving it.
How to do that? I doing it in c#
this is how i do such a thing, but i know the file's name. this is method is called into an empty aspx page (i mean without any kind of html markup except the <#Page ... /> line )
private void LoadAttachment()
{
byte[] ImageData = ... get data from somewhere ...
Response.Buffer = true;
String filename = "itakethis.fromdatabase";
Response.AddHeader("Content-Disposition", "attachment;filename=" + filename);
Response.ContentType = GetMimeType(filename);//you can try to extrapolate it from file extension
if(ImageData.Length > 0)
Response.BinaryWrite(ImageData);
else
Response.BinaryWrite(new byte[1]);
Response.Flush();
ApplicationInstance.CompleteRequest();
}
`
You can use MemoryStream to use the document only in RAM.
Unfortunately most programs (Word, Excel, Notepad, ...) need a filename to open a file. So i think there is no real solution to your problem.
The only think would be to write a File System Filter Driver, that returns the MemoryStream for a virtual filename, but that driver has to be written in C++ and is not the easiest one to do.
Why can't you save the file?
I've used GetTempFilename to good effect in the past. I can't remember exactly which class it's in, probably System.Environment or File itself. Anyway, you can be sure the file will be in the system defined temp folder, so you can safely delete the file once you're done with it.
Related
I'm doing the file attachment through memory stream because temporary storage is not an option.
Here I did a Jpeg image attachment. I looked at other file types with which you could do the same by switching the MediaTypeNames, and unfortunately .doc and .docx is not among them.
I was wondering whether any of you know of any package and how to use it for this particular occasion?
//...set up MailMessage, add a bunch of non-file content to it
MemoryStream jpgStream = new MemoryStream();
string filename = uploadedFile.FileName;
System.Drawing.Image theImage = System.Drawing.Image.FromStream(uploadedFile.InputStream);
theImage.Save(jpgStream, System.Drawing.Imaging.ImageFormat.Jpeg);
jpgStream.Seek(0L, SeekOrigin.Begin);
emailMessage.Attachments.Add(new Attachment(jpgStream, filename, System.Net.Mime.MediaTypeNames.Image.Jpeg));
//something extra and send email...
You should use MediaTypeNames.Application.Octet as mime type.
From : https://learn.microsoft.com/fr-fr/dotnet/api/system.net.mime.mediatypenames.application.octet?view=netframework-4.7.2
Thanks Benoit Gidon for his answer. I was proved once again that your assumptions are your worst enemy.
Apparently it's as simple as that and you don't need any other special methods as long as you put the file.InputStream in directly into attachment, unlike other S.O. posts make you believe:
https://stackoverflow.com/questions/9095880/attach-multiple-image-formats-not-just-jpg-to-email
https://stackoverflow.com/questions/5336239/attach-a-file-from-memorystream-to-a-mailmessage-in-c-sharp
In case anyone is actually struggling with it, here is the code:
foreach (HttpPostedFileBase file in fullViewModel.filesCollection)
{
string filename = file.FileName;
msg.Attachments.Add(new Attachment(file.InputStream, filename, MediaTypeNames.Application.Octet));
}
I tested this with a .docx document that had 5000 words of content in it, as well as tables and pictures, and it gets reconstructed the way it was in my gmail client.
Just tested that, it also works the same way with .png, so no need for PngBitmapDecoder.
I am using ASP.NET and I prefer VB as the language, but I should be able to translate C# for my needs.
I have an array of strings which I would like to send to the browser as individual files for the user to save. In searching the internet, the most common solution to send multiple files to a browser is to zip them up, and send a single zip file.
Towards that end, I need to learn a few things I do not know;
1) What tool/methods (preferably built in to ASP.NET running on IIS7) can I use to create a zip filestream to send to a browser?
2) How do I fool the zip tool into thinking it is getting multiple files from strings in memory? I assume I need to create filestreams, but how do I tell the methods what the file name is, etc.?
If there is an example of doing something substantially similar to what I need available, that would be great. Just point me at it.
Thanks for the help.
The approach could be:
Convert the string into stream
Add data from that stream into the zip file
Write the zip file into response stream
Code example below:
ZipFile zipFile = new ZipFile();
int fileNumber = 1;
foreach(string str in strArray)
{
// convert string to stream
byte[] byteArray = Encoding.UTF8.GetBytes(contents);
MemoryStream stream = new MemoryStream(byteArray);
stream.Seek(0, SeekOrigin.Begin);
//add the string into zip file with a name
zipFile.AddEntry("String" + fileNumber.ToString() + ".txt", "", stream);
}
Response.ClearContent();
Response.ClearHeaders();
Response.AppendHeader("content-disposition", "attachment; filename=strings.zip");
zipFile.Save(Response.OutputStream);
zipFile.Dispose();
I am having a really weird issue with my image saving method. First, here is the method:
public static void uploadImageToServer(string savePath, HttpPostedFile imageToUpload, bool overwrite)
{
byte[] myData = new Byte[imageToUpload.ContentLength];
imageToUpload.InputStream.Read(myData, 0, imageToUpload.ContentLength);
FileStream newFile = new FileStream(savePath, FileMode.Create);
newFile.Write(myData, 0, myData.Length);
newFile.Close();
}
As you can see from the input parameters this method works in conjuction with the FileUpload control. Now I am using this method from two pages which both have a FileUpload control. On one page the image uploads file, on the other page it results in a corrupted file.
I am really at a loss as to why the image is being corrupted. I am using the same image, the same method, and the same input control.
Is there any way I can debug this?
Gonna steal alexn's answer <_<
You are over-complicating it. Just use the built-in FileUpload::SaveAs(save_path) that is provided for you.
You can use the Server.MapPath() method to help you get a dynamic path to your root directory, go from there and append the file name to it.
Not sure why you are getting that error. My best guess is either your savePath is broken (or the filename/extension appended to it), or the bytes are not being read/written to perfectly.. Anyway, you should not get that error by using the method I described (considering you don't mess up the file extension :).
I have a process that creates a PDF. I want these PDF's to be temporary and short lived. I want to be able to perform the following when the user clicks a button:
string CreatePDF()//returns fileName.pdf
PromptUserToDownloadPDF()
DeletePDF(fileName.pdf)
I want to avoid having to create a cleanup procedure and deal with any race conditions that arise from users concurrently creating PDF's while running cleanup.
In winforms, I would synchronously prompt a user to download a file. How can I do a similar task in web?
UPDATE
Please note that I am using a 3rd party app to create the PDF's (Apache FOP). Basically I (will) have a function that invokes the command line:
C:>fop "inputfile" "output.pdf"
So, in memory is not an option...that is unless I could somehow do like....
string CreatePDF()//returns fileName.pdf
string RecreatePDFInMemory()
DeletePDF(fileName.pdf)
PromptUserToDownloadPDF()
Something like this:
byte[] _pdfbytes = CreatePDF();
Response.ContentType = "application/pdf";
Response.AppendHeader("Content-Length", _pdfbytes.Length.ToString());
Response.BinaryWrite(_pdfbytes);
Since this creates the PDF in memory, you don't need to worry about cleanup.
Edit for OP's edit:
From within CreatePDF, You can use Path.GetTempFileName to create a temp file and execute "fop" to write to that file. Delete that file immediately before returning the byte[]. I recommend doing this delete inside of a finally block. However, "Fop" does support having its output piped to stdout. Having the CreatePDF function grab that is probably cleaner.
Look into doing something along these lines.
Similar to what someone referred to in a different answer, you don't need to save the PDF file on your system, you can just send it as a response.
I'm not sure how you're creating your PDF, but try looking into this below and seeing if your process could use something like this.
HttpResponse currentResponse = HttpContext.Current.Response;
currentResponse.Clear();
currentResponse.ClearHeaders();
currentResponse.ContentType = "application/pdf";
currentResponse.AppendHeader("Content-Disposition", "attachment; filename=my.pdf");
//create the "my.pdf" here
currentResponse.Flush();
currentResponse.End();
Not sure of your process but you should be able to write the PDF to a byte[] and skip writing to the disk altogether.
byte[] pdf = GetPDFBytes(filename)
MemoryStream pdfStream = new MemoryStream(pdf);
Then use the pdfStream to send back to a user.
You can stream out a file with an asp.net page.
I tried to find very old article for you which demonstrates this with a GIF (there's not an actual file)
http://www.informit.com/articles/article.aspx?p=25487
It makes a special page which streams out the data (sets content type appropriately in the header).
Similarly, you can make a "page" to stream out the PDF - it might not even need to ever reside on disk, but if it did, you could delete it after streaming it to the browser.
I'm using C# and ASP.NET 2.5.
I want a simple way to generate a "file" on-the-fly (let's say a csv file for this example) and transmit it to the client without actually writing it to the server file system.
After some searching and trial and error, I developed the following. It seems to fit the bill exactly. It should be very easily adaptable to PHP or any other server-side software since it mostly involves modifying headers.
protected void streamToResponse()
{
Response.Clear();
Response.AddHeader("content-disposition", "attachment; filename=testfile.csv");
Response.AddHeader("content-type", "text/csv");
using(StreamWriter writer = new StreamWriter(Response.OutputStream))
{
writer.WriteLine("col1,col2,col3");
writer.WriteLine("1,2,3");
}
Response.End();
}
May I also suggest, that if you have something other than text, say, binary, you use the Response.WriteBinary() method
I've often created a JPG on the fly, wrote it to a MemoryStream using the Bitmap.Save() method, turned the MemoryStream into a byte[] array using .ToArray() and then Response.WriteBinary() that array.
Use the MemoryStream Class:
http://msdn.microsoft.com/en-us/library/system.io.memorystream.aspx