Split zip file using DotNetZip Library - asp.net

I'm using DotNetZip Library to create a zip file with about 100MB.I'm saving the zip file directly to the Response.OutputStream
Response.Clear();
// no buffering - allows large zip files to download as they are zipped
Response.BufferOutput = false;
String ReadmeText= "Dynamic content for a readme file...\n" +
DateTime.Now.ToString("G");
string archiveName= String.Format("archive-{0}.zip",
DateTime.Now.ToString("yyyy-MMM-dd-HHmmss"));
Response.ContentType = "application/zip";
Response.AddHeader("content-disposition", "attachment; filename=" + archiveName);
using (ZipFile zip = new ZipFile())
{
// add a file entry into the zip, using content from a string
zip.AddFileFromString("Readme.txt", "", ReadmeText);
// add the set of files to the zip
zip.AddFiles(filesToInclude, "files");
// compress and write the output to OutputStream
zip.Save(Response.OutputStream);
}
Response.Close();
what i need is to split this 100MB file in to with about 20MB sections and provide the download facility to the user.how can i achieve this?

Your question is sort of independent of the ZIP aspect. Basically it seems you want to make available for download a large file of 100mb or more, and you want to do it in parts. Some options:
Save it to a regular file, then transmit it in parts. The client would have to make a distinct download request for each of the N parts, selecting the appropriate section of the file via the HTTP Range header. The server would have to be set up to server ZIP files with the appropriate MIME type etc.
save it to a split (spanned) zip file, which implies N different files. The client would then make an HTTP GET for each of the distinct files. The server would have to be set up to server .zip, .z00, .z01, etc. I'm not sure if built-in OS tools handle split zip files appropriately.
save the file as one large blob, and have the client use BITS or some other restartable download facility.

Related

Upload dynamically created XML file using SFTP guidance

Currently I am generating an xml file for download using posted fields with the following code:
string attachment = "attachment; filename=" + FileName + ".xml";
Response.ClearContent();
Response.ContentType = "application/xml";
Response.AddHeader("content-disposition", attachment);
Response.Write(Session["FileForDownload"]);
Response.End();
This is working fine.
However I want to sftp upload the generated file to a specified directory on a server.
I have had success in connecting using ssh.net and have been able to create a new directory etc.
My question is how can I generate the file and then sftp it using ssh.net?
I've tried using a file stream with no success. I'm guessing the file needs to be temporarily stored and then retrieved for upload.
This is my current code segment for the specified problem:
SftpClient sftp = new SftpClient("host", "user", "pwd");
sftp.Connect();
sftp.ChangeDirectory("directory/");
Stream fs = File.OpenRead(Server.MapPath(#"filetobeuploaded"));
sftp.UploadFile(fs, Session["FileName"].ToString());
sftp.Disconnect();
I recognize that there won't be a file already on the server to upload.
Any help would be much appreciated as this is the final piece of the puzzle in my application.
Cheers
Fixed: I found a solution by generating a temp XML file in the server, uploading and deleting it. Thanks for your reply anyway

File upload in servlet corrupts the file

I am uploading a file using using (Valums uploader) and I using servlet at server side. File type is application/pdf. Code is :
String filename= request.getHeader("X-File-Name");
InputStream is = request.getInputStream();
File tmp = File.createTempFile(filename, "");
tmp.deleteOnExit();
FileOutputStream fos = new FileOutputStream(tmp);
IOUtils.copy(is, fos);
byte[] bytes = new byte[(int) tmp.length()];
is.read(bytes);
Now these bytes are getting stored into database as longblob. But it seems that inputStream in above code is adding some more data in the file thats why file data is getting corrupted. I download the same data as pdf file, found that both- original uploaded file and now downloaded file have the same size, but when the downloaded file is opened in Acrobat, it reports "File is corrupted". For upload request I have used only file input. So there are no chances of other input params in inputStream. Also the bytes array in above code are as it is passed for download. Why is data getting corrupted?
Your problem might be the data length you are reading. I had similar problem and posted on this issue link
Java: Binary File Upload using Restlet + Apache Commons FileUpload
Hope this helps

Extracting zip from stream with DotNetZip

public void ZipExtract(Stream inputStream, string outputDirectory)
{
using (ZipFile zip = ZipFile.Read(inputStream))
{
Directory.CreateDirectory(outputDirectory);
zip.ExtractSelectedEntries("name=*.jpg,*.jpeg,*.png,*.gif,*.bmp", " ", outputDirectory,
ExtractExistingFileAction.OverwriteSilently);
}
}
[HttpPost]
public ContentResult Uploadify(HttpPostedFileBase filedata)
{
var path = Server.MapPath(#"~/Files");
var filePath = Path.Combine(path, filedata.FileName);
if (filedata.FileName.EndsWith(".zip"))
{
ZipExtract(Request.InputStream,path);
}
filedata.SaveAs(filePath);
_db.Photos.Add(new Photo
{
Filename = filedata.FileName
});
_db.SaveChanges();
return new ContentResult{Content = "1"};
}
I try to read zip archive from stream and extract files. Got the following exception in the line "using (ZipFile zip = ZipFile.Read(inputStream))" : ZipEntry::ReadDirEntry(): Bad signature (0xC618F879) at position 0x0000EE19
Any ideas how to handle this exception?
The error is occurring because the stream you are trying to read is not a valid zip bytestream. In most cases, Request.InputStream will not represent a zip file. It will represent an HTTP message, which will look like this:
POST /path/for/your/app.aspx HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.2; ...)
Content-Type: application/x-www-form-urlencoded
Content-Length: 11132
...more stuff here...
I think what you are doing is trying to read that message as if it were a zip file. That's not gonna work. The file content is actually embedded in the "... more stuff here..." part.
To work toward solving this, I suggest you work in smaller steps.
First, get the file upload to work, saving the content of the uploaded file to a filesystem file on the server. Then, on the server, try to open the file as a zipfile. If it works, then you should be able to replace the file saving portion, with ZipFile.Read(). If you cannot open the file that you saved, then it means that the file that you saved is not a zip file. Either it is incomplete, or, more likely, it includes extraneous data, like the HTTP headers.
If you have trouble successfully uploading a binary file like a zip file, first work on uploading a text file. You can more easily verify the upload of a text file on the server, by simply opening the uploaded content in a text editor, and checking that it contains exactly the content of the file that was uploaded from the client. Once you have this working, move to a binary file. Then you can move to a full streaming approach, using DotNetZip to read the stream. Once you get to this point, there should be no need to save the file to the filesystem, before reading it as a zip file, but you may want to save it anyway, for other reasons.
To help, you may want to use Fiddler2, the debugging HTTP proxy. Install it on the browser machine, turn it on, and it will help you see the messages that get sent from the browser to the ASPNET application on the server. You'll see that a file upload contains more that just the bare file data.
A more stable solution could be to use ICSharpCode ZipLib: http://www.sharpdevelop.net/OpenSource/SharpZipLib/Default.aspx

Viewing file using asp.net

In our application, we allow user to upload documents which can be PDF, Doc, XLS, TXT. Uploaded documents will be saved on web server. We need to display link for each document user uploaded and when user click on that link, it should open relevant document. it is expected to have required software to open relevant documents.
To upload document, we use saveAs method of FileUpload control and it works absolutely fine.
Now, how to view it?
I believe, i need to copy/download file to local user machine and need to open it using Process.Start.
For that i need to find user local temp directory. if i put path.GetTempPath(), it gives me web server directory and copy file there.
File.Copy(
sPath + dataReader["url"].ToString(),
Path.GetTempPath() + dataReader["url"].ToString(),
true);
Please advise.
You can't write to the user's drive from the webserver.
What you can do is just provide a link that will download the file to the client.
Set the Content-Disposition header to "attachment" to have a "save as" dialog come up, or to "inline" to let it display in the browser using the registered program from the client.
You can create a LinkButton with a server side handler that contains code like this:
byte[] data = ...; // get the data from database or whatever
Response.Clear(); // no contents of the aspx file needed
Response.CacheControl = "private";
Response.ContentType = "application/pdf"; // or whatever the mimetype of your file is
Response.AppendHeader("Content-Disposition", "attachment;filename=statistic.pdf");
Response.AppendHeader("Content-Length", data.Length.ToString(CultureInfo.InvariantCulture));
Response.BinaryWrite(data);
Response.End(); // no further processing of the page needed
Can you not just put a link on the page pointing to the directory that the files are in?
e.g.
<a href=downloadedfiles/filename.pdf> click here </a>
Once you've provided the link, your job is done. Mostly. The client's browser will handle loading the file when the link is clicked, if it can handle the file type based on the file extension.
I prefer to use a http handler for referencing file links on a web page. This will be important on the day when you need to implement security for uploaded file access; otherwise, any user could access any file.
You don't have to download the file to user machine.
// For pdf documents
Response.Clear();
string filePath = "File path on the web server";
Response.ContentType = "application/pdf"; // for pdf
Response.WriteFile(filePath);
// For word documents
Response.Clear();
string filePath = "File path on the web server";
Response.ContentType = "application/msword";
Response.WriteFile(filePath);
// similarly other file types

How do I optimise file downloads in ASP.NET?

I have ASP.NET application which allows users to download a file when he/she enters a password. I use code below to send file to user:
Context.Response.Clear();
Context.Response.ContentType = "application/pdf";
Context.Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
Context.Response.BinaryWrite(File.ReadAllBytes(fileName));
Context.Response.Flush();
Context.Response.Close();
The problem is that the downloads become very slow if the files are more than 1mb or many users are downloading files at the same time. Is it possible somehow to optimize code for better performance?
You might use Response.TransmitFile(/* Your file */); instead of Response.BinaryWrite(/* Your file */);
The TransmitFile()-Method writes the data to the HTTP output stream without storing it in the memory.
Why are you managing the downloads manually? Why not just put a link to the appropriate PDF file on the page that is shown after a successful login? This will free up the ASP.NET threads so you don't use them to manage the file download. IIS will still have to serve them up but I think it would reduce your overhead significantly.
Are you worried about the file name being exposed? If so, reply - there are a few other options you can explore.

Resources