使用 FtpWebRequest 下载时,zip 的大小会增加
本文关键字:增加 zip FtpWebRequest 下载 使用 | 更新日期: 2023-09-27 18:33:25
我有一些供内部使用的实用程序类,可以从FTP服务器下载文件。过去,所有这些都是纯文本文件,并且可以正常工作。但是,我们现在有一些压缩文件,我希望它下载。在本地写入此文件时,大小从 ~80 Kb 更改为 ~140 Kb。为什么文件在写入过程中会损坏?为什么这不适用于普通文本文件?要使此代码适用于所有文件类型,需要进行哪些更改?
private static string GetFile(string file, bool inBound)
{
string path;
if (inBound)
path = Config.settings["FTPIn"] + file;
else
path = Config.settings["FTPOut"] + file;
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(path);
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.Credentials = new NetworkCredential(Config.Settings["FTPUser"], Config.Settings["FTPPass"]);
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
string file_contents = System.String.Empty;
using (Stream responseStream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(responseStream))
{
try
{
file_contents = reader.ReadToEnd();
}
catch (Exception e)
{
ResultLogger.LogVerbose(trGuid, "Exception while getting file from FTP share.");
ResultLogger.LogVerbose(trGuid, e.Message);
ResultLogger.LogVerbose(trGuid, e.StackTrace);
}
reader.Close();
response.Close();
}
}
return file_contents;
}
请注意,没有运行时错误(至少在其他代码尝试解压缩文件之前没有),文件只是在写入过程中损坏。
另外,调用代码如下;
string file_contents = GetFile(fileName, inBound);
File.WriteAllText(@".'" + fileName, file_contents);
return new FileInfo(@".'" + fileName);
您不想将原始数据读入字符串,而应将其读入字节数组。 .NET 字符串由两个字节字符组成。
你应该使用 BinaryReader
,或者更好的是,将其直接写入文件,而无需先将其读入内存,使用 CopyTo()
private static void GetFile(string file, bool inBound)
{
// Removed the FTP setup code
using (Stream responseStream = response.GetResponseStream())
{
using (Stream outputStream = File.OpenWrite(@".'" + file))
{
try
{
responseStream.CopyTo(outputStream);
}
catch (Exception e)
{
// Removed Exception code
}
}
}
}
您的问题是下载二进制文件时需要设置request.UseBinary = true;
。 否则,FTP 流会将无效的二进制值转换为有效的字符串值,以便通过网络发送。 这就是导致下载时大小增加以及"损坏"文件的原因,因为您当前没有考虑这种差异。 代码应如下所示:
更新:我刚刚注意到您也将其作为字符串返回。 我修改了代码以正确读取和填充缓冲区以返回二进制文件。
private static byte[] GetFile(string file, bool inBound)
{
string path;
if (inBound)
path = Config.settings["FTPIn"] + file;
else
path = Config.settings["FTPOut"] + file;
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(path);
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.UseBinary = true;
request.Credentials = new NetworkCredential(Config.Settings["FTPUser"], Config.Settings["FTPPass"]);
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
byte[] file_contents = null;
using (Stream responseStream = response.GetResponseStream())
{
byte[] buffer = new byte[2048];
using (MemoryStream ms = new MemoryStream())
{
int readCount = responseStream.Read(buffer, 0, buffer.Length);
while (readCount > 0)
{
ms.Write(Buffer, 0, readCount);
readCount = responseStream.Read(buffer, 0, buffer.Length);
}
file_contents = ms.ToArray();
}
}
return file_contents;
}