What's wrong with this file write code

C

Cal Who

This code works OK if the file is small but if the "do" loop has to iterate
a second time the file is NG.

When I open the zip the file is there but if I try to copy it or open it the
system ignores my command.

I debug and see the loop traversed more than once to produce a problem file.

The file for which it only passes the code once are OK

I copied this code. It did not have the CloseEntry and had the problem
before I added it.

Better with it or without?

Can you tell me how to fix this?

Or something to try?

Thanks



private void ZipAllFiles()

{

byte[] buffer = new byte[4096];


// the path on the server where the temp file will be created!

var tempFileName = Server.MapPath(@"~/Tmp.zip");

var zipOutputStream = new ZipOutputStream(File.Create(tempFileName));

var filePath = String.Empty;

var fileName = String.Empty;

var readBytes = 0;

foreach(GridViewRow row in gvFiles.Rows)

{

var isChecked = (row.FindControl("chkSelect") as CheckBox).Checked;

if (!isChecked) continue;

filePath = (row.FindControl("lblFilePath") as Label).Text;

fileName = (row.FindControl("lblFileName") as Label).Text;

var zipEntry = new ZipEntry(fileName);

zipOutputStream.PutNextEntry(zipEntry);

using(var fs = File.OpenRead(filePath))

{

do

{

readBytes = fs.Read(buffer, 0, buffer.Length);

zipOutputStream.Write(buffer,0,readBytes);

} while (readBytes > 0);

zipOutputStream.CloseEntry(); //CAG added

}

}

if (zipOutputStream.Length == 0)

{

lblMessage.Text = "Please select at least one file!";

return;

}?

zipOutputStream.Finish();

zipOutputStream.Close();

Response.ContentType = "application/x-zip-compressed";

Response.AppendHeader("Content-Disposition", "attachment;
filename=YourFile.zip");

Response.WriteFile(tempFileName);

Response.Flush();

Response.Close();

// delete the temp file

if(File.Exists(tempFileName))

File.Delete(tempFileName);

}

}
 
C

Cal Who

I've tried a few different ways to write - all with the same effect: if the
file is not small the result in the zip file is NG.
using (var fs = File.OpenRead(filePath))

{

//while ((readBytes = fs.Read(buffer, 0, buffer.Length)) > 0)

//{

// zipOutputStream.Write(buffer, 0, readBytes);

//}

//=====

//do

//{

// readBytes = fs.Read(buffer, 0, buffer.Length);

// if (readBytes > 0) zipOutputStream.Write(buffer,0,readBytes);

//} while (readBytes > 0);

//zipOutputStream.CloseEntry(); //CAG added

//=====?

?

//zipOutputStream.SetLevel(9);

byte[] byteBuffer = new byte[fs.Length - 1];

fs.Read(byteBuffer, 0, byteBuffer.Length);

zipOutputStream.Write(byteBuffer, 0, byteBuffer.Length);

zipOutputStream.CloseEntry();

?

}

Got any ideas?

Maybe I should start a new thread pointing to SharpZipLibrary.

Maybe that has a problem - though I have searched for that!



Thanks






Cal Who said:
This code works OK if the file is small but if the "do" loop has to
iterate a second time the file is NG.

When I open the zip the file is there but if I try to copy it or open it
the system ignores my command.

I debug and see the loop traversed more than once to produce a problem
file.

The file for which it only passes the code once are OK

I copied this code. It did not have the CloseEntry and had the problem
before I added it.

Better with it or without?

Can you tell me how to fix this?

Or something to try?

Thanks



private void ZipAllFiles()

{

byte[] buffer = new byte[4096];


// the path on the server where the temp file will be created!

var tempFileName = Server.MapPath(@"~/Tmp.zip");

var zipOutputStream = new ZipOutputStream(File.Create(tempFileName));

var filePath = String.Empty;

var fileName = String.Empty;

var readBytes = 0;

foreach(GridViewRow row in gvFiles.Rows)

{

var isChecked = (row.FindControl("chkSelect") as CheckBox).Checked;

if (!isChecked) continue;

filePath = (row.FindControl("lblFilePath") as Label).Text;

fileName = (row.FindControl("lblFileName") as Label).Text;

var zipEntry = new ZipEntry(fileName);

zipOutputStream.PutNextEntry(zipEntry);

using(var fs = File.OpenRead(filePath))

{

do

{

readBytes = fs.Read(buffer, 0, buffer.Length);

zipOutputStream.Write(buffer,0,readBytes);

} while (readBytes > 0);

zipOutputStream.CloseEntry();
}

}

if (zipOutputStream.Length == 0)

{

lblMessage.Text = "Please select at least one file!";

return;

}?

zipOutputStream.Finish();

zipOutputStream.Close();

Response.ContentType = "application/x-zip-compressed";

Response.AppendHeader("Content-Disposition", "attachment;
filename=YourFile.zip");

Response.WriteFile(tempFileName);

Response.Flush();

Response.Close();

// delete the temp file

if(File.Exists(tempFileName))

File.Delete(tempFileName);

}

}
 
A

Andrew Morton

Cal said:
I've tried a few different ways to write - all with the same effect:
if the file is not small the result in the zip file is NG.

NG=not good or not generated?

If you're using Windows' native ability to open zip files, you will have to
set the .Size for the entry, or it won't work.

In VB, a working section of code to zip up a collection of files is:

Imports ICSharpCode.SharpZipLib.Core
Imports ICSharpCode.SharpZipLib.Zip

Dim zipFileName As String = "someFile.zip"
Dim zipFile As String =
Path.Combine(Path.Combine(HttpContext.Current.Request.PhysicalApplicationPath,
"downloads"), zipFileName)
Dim zos As ZipOutputStream = New ZipOutputStream(File.Create(zipFile))
Dim entry As ZipEntry
Dim fs As FileStream
Dim buffer(4095) As Byte ' I think that would be 4096 in C#
Dim actualFile As String

zos.SetLevel(2) ' use mild compression as we're packing in jpg files

' bung them all in one file first to get that over and done with
For Each filename As String In filelist
actualFile =
Path.Combine(Path.Combine(HttpContext.Current.Request.PhysicalApplicationPath,
imgSrcFolder), filename)
' name the entry the filename w/o path
entry = New ZipEntry(filename)
' must set size to get WinXP zip decoder to work
entry.Size = New FileInfo(actualFile).Length
zos.PutNextEntry(entry)
fs = System.IO.File.OpenRead(actualFile)
StreamUtils.Copy(fs, zos, buffer)
fs.Close()
Next

zos.Close()

HTH
 
A

Alexey Smirnov

This code works OK if the file is small but if the "do" loop has to iterate
a second time the file is NG.

I see that you read the content into buffer of 4096 bytes.
Try to use following code

ZipOutputStream zipOut = new
ZipOutputStream(File.Create(zipFullPath));
FileInfo fi = new FileInfo(fName);
ZipEntry entry = new ZipEntry(fi.Name);
FileStream sReader = File.OpenRead(fName);
byte[] buff = new byte[Convert.ToInt32(sReader.Length)];
sReader.Read(buff, 0, (int) sReader.Length);
entry.DateTime = fi.LastWriteTime;
entry.Size = sReader.Length;
sReader.Close();
zipOut.PutNextEntry(entry);
zipOut.Write(buff, 0, buff.Length);
zipOut.Finish();
zipOut.Close();

Hope this helps
 
C

Cal Who

This code works OK if the file is small but if the "do" loop has to
iterate
a second time the file is NG.

I see that you read the content into buffer of 4096 bytes.
Try to use following code

ZipOutputStream zipOut = new
ZipOutputStream(File.Create(zipFullPath));
FileInfo fi = new FileInfo(fName);
ZipEntry entry = new ZipEntry(fi.Name);
FileStream sReader = File.OpenRead(fName);
byte[] buff = new byte[Convert.ToInt32(sReader.Length)];
sReader.Read(buff, 0, (int) sReader.Length);
entry.DateTime = fi.LastWriteTime;
entry.Size = sReader.Length;
sReader.Close();
zipOut.PutNextEntry(entry);
zipOut.Write(buff, 0, buff.Length);
zipOut.Finish();
zipOut.Close();

Hope this helps

Thank you
 
Top