سؤال

واني اسعى الى تحميل الملفات من خادم بروتوكول نقل الملفات باستخدام C # و FtpWebRequest يتم. يمكنني الحصول بايت باستخدام BinaryReader، ولكن عندما أحاول قراءة دفق باستخدام br.ReadBytes (الباحث)، وأحصل على خطأ 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، من الممكن أنه يمكن أن تكون خاطئة. تحتاج فقط إلى قراءة كافة وحدات البايت في حين حلقة حتى لا توجد أكثر بايت للقراءة.

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 ويعمل كبيرة! هنا هو رمز وأخيرا حصلت على العمل قبل أن أرى منصبه. انها مختلفة قليلا ب / ج فإنه يكتب مباشرة إلى ملف بدلا من دفق الذاكرة.

وأنا محل هذا السطر:

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 مع الإسناد
لا تنتمي إلى StackOverflow
scroll top