[英]C# BinaryReader “stream does not support seek operations”
我試圖使用C#和ftpwebrequest從ftp服務器下載文件。 我可以使用BinaryReader獲取字節,但是當我嘗試使用br.ReadBytes(int)讀取流時,我得到一個BinaryReader不支持搜索操作的錯誤。
有誰知道如何最好地讀取字節,以便我可以將它們寫入文件?
這是完整的方法:
public void DownloadFile(String fileName)
{
Logger.Info("starting to download file: " + fileName);
try
{
var downloadFileRequest = (FtpWebRequest)WebRequest.Create(FtpServer + "//" + fileName);
downloadFileRequest.Credentials = new NetworkCredential(FtpUsername,FtpPassword);
downloadFileRequest.Method = WebRequestMethods.Ftp.DownloadFile;
downloadFileRequest.UseBinary = true;
ServicePoint sp = downloadFileRequest.ServicePoint;
sp.ConnectionLimit = 2;
Logger.Info("getting ftp response for download file for " + fileName);
try
{
var downloadResponse = (FtpWebResponse)downloadFileRequest.GetResponse();
Logger.Info("getting ftp response stream for " + fileName);
try
{
Stream downloadStream = downloadResponse.GetResponseStream();
Logger.Info("File Download status: {0}", downloadResponse.StatusDescription.Trim());
Logger.Info("getting binary reader for " + fileName);
try
{
using ( var downloadReader = new BinaryReader(downloadStream))
{
String destinationFilePath= Path.Combine(LocalFolder, fileName);
Logger.Info("writing response stream to " + destinationFilePath);
try
{
using (var downloadWriter = new BinaryWriter(System.IO.File.Open(destinationFilePath, FileMode.Create)))
{
downloadWriter.Write(downloadReader.ReadBytes((int)downloadStream.Length));
}
Logger.Info("successfully saved " + destinationFilePath);
}
catch (Exception ex)
{
Logger.Info("could not save " + destinationFilePath+ " b/c: " + ex.Message);
}
}
}
catch (Exception ex)
{
Logger.Info("could not read " + fileName + " b/c: " + ex.Message);
}
}
catch (Exception ex)
{
Logger.Info("could not open download stream for " + fileName + " b/c: " + ex.Message);
}
finally
{
downloadResponse.Close();
}
}
catch (Exception ex)
{
Logger.Info("could not get ftp response stream for " + fileName + " b/c: " + ex.Message);
}
}
catch (Exception ex)
{
Logger.Info("could not get ftp request stream for " + fileName + " b/c: " + ex.Message);
}
}
這是正在進行的服務的一部分,所以我不想拋出會阻止服務的錯誤。 相反,我正在寫日志。 以下是此方法的日志內容:
2009-10-07 16:33:29.1421|INFO|xxx.Web.Controllers.FtpController|starting to download file: 2009-10-06155728Z_metadata.txt
2009-10-07 16:33:29.1421|INFO|xxx.Web.Controllers.FtpController|getting ftp response for download file for 2009-10-06155728Z_metadata.txt
2009-10-07 16:33:29.6661|INFO|xxx.Web.Controllers.FtpController|getting ftp response stream for 2009-10-06155728Z_metadata.txt
2009-10-07 16:33:29.6661|INFO|xxx.Web.Controllers.FtpController|File Download status: 125 Data connection already open; Transfer starting.
2009-10-07 16:33:29.6721|INFO|xxx.Web.Controllers.FtpController|getting binary reader for 2009-10-06155728Z_metadata.txt
2009-10-07 16:33:29.6721|INFO|xxx.Web.Controllers.FtpController|writing response stream to C:\\Resumes\\2009-10-06155728Z_metadata.txt
2009-10-07 16:33:29.6951|INFO|xxx.Web.Controllers.FtpController|could not save C:\\Resumes\\2009-10-06155728Z_metadata.txt b/c: This stream does not support seek operations.
我一直在這方面工作太久了,所以任何幫助都將不勝感激!
謝謝!!
你不應該依賴Stream.Length
,它可能是錯誤的。 您只需要讀取while循環中的所有字節,直到沒有更多字節要讀取。
MemoryStream ms = new MemoryStream();
byte[] chunk = new byte[4096];
int bytesRead;
while ((bytesRead = downloadStream.Read(chunk, 0, chunk.Length)) > 0)
{
ms.Write(chunk, 0, bytesRead);
}
從那里,所有讀取數據都在MemoryStream
,您可以用它初始化BinaryReader
。
Darkassassin的答案很棒! 這是我在看到他的帖子之前最終開始工作的代碼。 b / c略有不同,它直接寫入文件而不是內存流。
我替換了這一行:
downloadWriter.Write(downloadReader.ReadBytes((int)downloadStream.Length));
有了這個:
var buffer = new byte[BufferSize];
int readCount = downloadStream.Read(buffer, 0, BufferSize);
while (readCount > 0)
{
downloadWriter.Write(buffer, 0, readCount);
readCount = downloadStream.Read(buffer, 0, BufferSize);
}
(BufferSize = 4096)
再次感謝您的快速幫助!!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.