asp.net implementation file download code

  • 2020-05-10 18:03:14
  • OfStack

 
public partial class FileDownLoad : System.Web.UI.Page 
{ 
// Provide download file, do not encode the file name will be garbled  
private string fileName = HttpContext.Current.Server.UrlEncode(" specification .rar"); 
private string filePath = HttpContext.Current.Server.MapPath(" specification .rar"); 
// use TransmifFile The download file  
protected void btnDL1_Click(object sender, EventArgs e) 
{ 
FileInfo info = new FileInfo(filePath); 
long fileSize = info.Length; 
Response.Clear(); 
Response.ContentType = "application/x-zip-compressed"; 
Response.AddHeader("Content-Disposition", "attachment;filename="+ fileName); 
// Don't specify Content-Length with Flush Will not show the download progress  
Response.AddHeader("Content-Length", fileSize.ToString()); 
Response.TransmitFile(filePath, 0, fileSize); 
Response.Flush(); 
Response.Close(); 
} 

// use WriteFile The download file  
protected void btnDL2_Click(object sender, EventArgs e) 
{ 
FileInfo info = new FileInfo(filePath); 
long fileSize = info.Length; 
Response.Clear(); 
Response.ContentType = "application/octet-stream"; 
Response.AddHeader("Content-Disposition", "attachement;filename=" + fileName); 
// Specify file size  
Response.AddHeader("Content-Length", fileSize.ToString()); 
Response.WriteFile(filePath, 0, fileSize); 
Response.Flush(); 
Response.Close(); 
} 

// use OutputStream.Write Download files in chunks  
protected void btnDL3_Click(object sender, EventArgs e) 
{ 
// Specify block size  
long chunkSize = 102400; 
// To establish 1 a 100K The buffer  
byte[] buffer = new byte[chunkSize]; 
// Number of bytes read  
long dataToRead = 0; 
FileStream stream = null; 
try 
{ 
// Open the file  
stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); 
dataToRead = stream.Length; 

// add Http head  
Response.ContentType = "application/octet-stream"; 
Response.AddHeader("Content-Disposition", "attachement;filename=" + fileName); 
Response.AddHeader("Content-Length", dataToRead.ToString()); 

while (dataToRead > 0) 
{ 
if (Response.IsClientConnected) 
{ 
int length = stream.Read(buffer, 0, Convert.ToInt32(chunkSize)); 
Response.OutputStream.Write(buffer, 0, length); 
Response.Flush(); 
Response.Clear(); 
dataToRead -= length; 
} 
else 
{ 
// To prevent client Lost connection  
dataToRead = -1; 
} 
} 
} 
catch (Exception ex) 
{ 
Response.Write("Error:" + ex.Message); 
} 
finally 
{ 
if (stream != null) 
{ 
stream.Close(); 
} 
Response.Close(); 
} 
} 

// use BinaryWrite Download files, large files are not efficient  
protected void btnDL4_Click(object sender, EventArgs e) 
{ 
FileStream stream = null; 
try 
{ 
// Read the file , A large file 1 Second reads can take up a lot of memory  
stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); 
byte[] bytes = new byte[stream.Length]; 
stream.Read(bytes, 0, bytes.Length); 
stream.Close(); 

// add Http head  
Response.ContentType = "application/octet-stream"; 
Response.AddHeader("Content-Disposition", "attachement;filename=" + fileName); 
Response.AddHeader("Content-Length", bytes.Length.ToString()); 
Response.BinaryWrite(bytes); 
Response.Flush(); 
} 
catch (Exception ex) 
{ 
Response.Write("Error:" + ex.Message); 
} 
finally 
{ 
if (stream != null) 
{ 
stream.Close(); 
} 
Response.Close(); 
} 
} 
// use BinaryWrite Download files in chunks  
protected void btnDL5_Click(object sender, EventArgs e) 
{ 
// Specify blocks and buffers  
long chunkSize = 102400; 
byte[] buffer = new byte[chunkSize]; 
FileStream stream = null; 
long dataToRead = 0; 
try 
{ 
stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); 
dataToRead = stream.Length; 
// add Http head  
Response.ContentType = "application/octet-stream"; 
Response.AddHeader("Content-Disposition", "attachement;filename=" + fileName); 
Response.AddHeader("Content-Length", dataToRead.ToString()); 

while (dataToRead > 0) 
{ 
if (Response.IsClientConnected) 
{ 
int length = stream.Read(buffer, 0, Convert.ToInt32(chunkSize)); 
Response.BinaryWrite(buffer); 
Response.Flush(); 
Response.Clear(); 

dataToRead -= length; 
} 
else 
{ 
dataToRead = -1; 
} 
} 

} 
catch(Exception ex) 
{ 
Response.Write("Error:" + ex.Message); 
} 
finally 
{ 
if (stream != null) 
{ 
stream.Close(); 
} 
Response.Close(); 
} 
} 
} 

All of the above are acceptable except for the fourth one, but I feel it is better to download them in chunks. Not tested carefully, so there could be a problem.

Note: the Chinese file name must be coded to display correctly. For the long Chinese file name (UTF8 after the encoding is greater than 153 bytes of Chinese), even if the encoding, there is still a problem, you can refer to the following article.

There have been a lot of online consultation and q&a about downloading Chinese files. The original code I used to handle downloading is as follows:

response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));
With this sentence in the downloaded program, the name of the file will be displayed correctly in the IE6 download prompt, either in simplified Chinese or Japanese. However, I did not test the long Chinese file names carefully. Now, after careful testing, it turns out that any text longer than 17 words is not downloadable. After a good google and repeated tests, I finally have a systematic understanding of this problem, which is listed as follows:

1. In my original way, URLEncoder was used for encoding. When Chinese characters exceed 17, IE6 cannot download the file. This is bug for IE, see Microsoft's knowledge base article KB816868. The reason may be that when ie processes Response Header, it limits the length of header to about 150 bytes. Whereas a Chinese character encoded as UTF-8 is 9 bytes, 17 characters are 153 bytes, so errors are reported. Microsoft offers a patch that can be downloaded here. This patch requires the installation of ie6 sp1. Because I patch frequently, my version number of IE6 is 6.0.2800.1106.xpsp2_xxxxx. So I may have installed the patch so I can download it, but the file name is still truncated. Microsoft has asked us to wait for the release of the next IE service pack. I also saw the good news online today. Under the pressure of firefox, IE7 may be released in the middle of the year. In addition, Firefox does not support such a method and will display the encoded %xx%xx directly as the file name.


2. I tried to use javamail's MimeUtility.encode () method to encode the file name, i.e. =? gb2312? B? xxxxxxxx? = and find the corresponding standard support from RFC1522. Unfortunately, IE6 does not support this standard. I tried 1, Firefox is supported.

3. According to the solution offered by many people on the Internet, encoding the file name as ISO8859-1 seems to be an effective solution, and the code is as follows:

response.setHeader( "Content-Disposition", "attachment;filename=" + new String( fileName.getBytes("gb2312"), "ISO8859-1" ) );

This is really the most effective way to ensure that the names of the attached files are all simplified Chinese characters, without having to upgrade IE on a customer-by-customer basis. If Taiwan compatriots use it, just change gb2312 to big5. But today's systems are generally supported by internationalization, and UTF-8 is widely used. If there are simplified Chinese characters, traditional Chinese characters, and Japanese characters in the file name. Then the garbled code comes into being. In addition, the download of Firefox(v1.0-en) on my computer is also garbled.

As a compromise, I combined the 1.3 approach with the following code snippet:
 
String fileName = URLEncoder.encode(atta.getFileName(), "UTF-8"); 
/* 
* see http://support.microsoft.com/default.aspx?kbid=816868 
*/ 
if (fileName.length() > 150) { 
String guessCharset = xxxx /* According to the request the locale  Get the possible code, the Chinese operating system is usually gb2312*/ 
fileName = new String(atta.getFileName().getBytes(guessCharset), "ISO8859-1"); 
} 
response.setHeader("Content-Disposition", "attachment; filename=" + fileName); 

Forget Firefox for the moment because it doesn't seem to be making a serious dent in the enterprise market for IE. It is often progress, not compatibility, that affects a customer's purchase.

Related articles: