Agarwal1984 Ответов: 2

Не читал, что zip-файл. Используя C#?


Привет,

У меня есть два файла один zip файл и другой текстовый файл но когда мы загружаем его так что он получает ошибку:-
когда я распаковываю файл, так что он получает ошибку:-
"Не могу прочитать это как ZipFile."
Я хочу загрузить все файлы с ftp и распаковать только zip-файл.

Ошибка в этой строке:-
string zipToUnpack = @"C:\" + file;
string unpackDirectory = @"C:\";
using (ZipFile zip1 = ZipFile.Read(zipToUnpack))
{
    foreach (ZipEntry ze in zip1)
    {
        ze.Extract(unpackDirectory, ExtractExistingFileAction.OverwriteSilently);
    }
}



Этот код успешно работает только с одним zip-файлом.
Только один файл распаковывается, но более одного не загружают zip-файл и текстовый файл, который получает ошибку "не может прочитать это как ZipFile".

Пожалуйста, помогите мне.
заранее спасибо.

Анкит Агарвал
инженер-программист

Что я уже пробовал:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            string[] files = ReadFileList();
            FTPSettings.IP = "xxxxxxxx/Test";
            FTPSettings.UserID = "xxxx";
            FTPSettings.Password = "xxxx";
            //FtpWebRequest reqFTP = null;
            //Stream ftpStream = null;
            foreach (string file in files)
            {
                //string fileName = e.Argument.ToString();

                FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://" + FTPSettings.IP + "/" + file);
                request.Credentials = new NetworkCredential(FTPSettings.UserID, FTPSettings.Password);
                request.Method = WebRequestMethods.Ftp.GetFileSize;
                request.Proxy = null;

                long fileSize; // this is the key for ReportProgress
                using (WebResponse resp = request.GetResponse())
                    fileSize = resp.ContentLength;

                request = (FtpWebRequest)WebRequest.Create("ftp://" + FTPSettings.IP + "/" + file);
                request.Credentials = new NetworkCredential(FTPSettings.UserID, FTPSettings.Password);
                request.Method = WebRequestMethods.Ftp.DownloadFile;
                using (FtpWebResponse responseFileDownload = (FtpWebResponse)request.GetResponse())
                using (Stream responseStream = responseFileDownload.GetResponseStream())
                using (FileStream writeStream = new FileStream(@"C:\" + file, FileMode.Create))
                {

                    int Length = 2048;
                    Byte[] buffer = new Byte[Length];
                    int bytesRead = responseStream.Read(buffer, 0, Length);
                    int bytes = 0;

                    while (bytesRead > 0)
                    {
                        writeStream.Write(buffer, 0, bytesRead);
                        bytesRead = responseStream.Read(buffer, 0, Length);
                        bytes += bytesRead;// don't forget to increment bytesRead !
                        int iProgress = 0;
                        int totalSize = (int)(fileSize) / 1000; // Kbytes
                        if (totalSize > 0)
                        {
                            iProgress = (bytes / 1000) * 100 / totalSize;
                        }
                        backgroundWorker1.ReportProgress(iProgress, totalSize);
                    }
                }
string zipToUnpack = @"C:\" + file;
                string unpackDirectory = @"C:\";
                using (ZipFile zip1 = ZipFile.Read(zipToUnpack))
                {
                    foreach (ZipEntry ze in zip1)
                    {
                        ze.Extract(unpackDirectory, ExtractExistingFileAction.OverwriteSilently);
                    }
                }
}

public string[] ReadFileList()
        {
            //Debugger.Break();
            string[] mydownloadFiles;
            StringBuilder myresult = new StringBuilder();
            //WebResponse myresponse = null;
            StreamReader myreader = null;
            FtpWebRequest myreqFTP = null;
            try
            {

                FTPSettings.IP = "xxxxxxx/Test";
                FTPSettings.UserID = "xxxx";
                FTPSettings.Password = "xxxx";
                myreqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + FTPSettings.IP + "/"));
                myreqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
                myreqFTP.UseBinary = true;

                myreqFTP.Credentials = new NetworkCredential(FTPSettings.UserID, FTPSettings.Password);
                FtpWebResponse response = (FtpWebResponse)myreqFTP.GetResponse();
                myreader = new StreamReader(response.GetResponseStream());
                string myline = myreader.ReadLine();
                while (myline != null)
                {
                    myresult.Append(myline);
                    myresult.Append("\n");
                    myline = myreader.ReadLine();
                }
                // to remove the trailing '\n'
                myresult.Remove(myresult.ToString().LastIndexOf('\n'), 1);
                return myresult.ToString().Split('\n');
            }
            catch (Exception ex)
            {
                if (myreader != null)
                {
                    myreader.Close();
                }
                mydownloadFiles = null;
                return mydownloadFiles;
            }
        }



public static class FTPSettings
        {
            public static string IP { get; set; }
            public static string UserID { get; set; }
            public static string Password { get; set; }
        }

Philippe Mori

Я надеюсь, что это не ваш настоящий код! Никогда не использует такой жестко закодированный путь. Нет никакой гарантии, что есть диск c: и что вы можете писать под ним.
Есть много других плохих практик, таких как:
- жестко постоянное (научиться не повторять самого себя - сухой),
- не использующий Path.Combine чтобы объединить части пути,
- использование static class для FTPSettings,
- объявление переменных перед их первым использованием,
- не используя using заявление для некоторых одноразовых предметов, когда он мог бы быть использован,
- не понимаю .Чистые соглашения,
- создание "длинной" строки для ее последующего разделения (вы должны были использовать список и при необходимости преобразовать его в массив в конце, так как это было бы гораздо эффективнее, если бы строка была несколько длинной),
- с помощью Remove и LastIndexOf когда вы могли бы использовать TrimEnd вместо этого (что является самодокументированием),
- функции, которые делают более одной вещи (узнайте о принципе единой ответственности-SRP),
- плохо названные переменные,
- дискутируемый отступ,
...

2 Ответов

Рейтинг:
18

Mycroft Holmes

Проверьте значение переменной TotalSize, прежде чем использовать ее для деления. Я бы поместил его в Оператор if

iProgress int = 0;
if(TotalSize > 0 ){iProgress = (bytes / 1000) * 100 / totalSize;}

backgroundWorker1.ReportProgress(iProgress, totalSize);


TotalSize может быть 0 из-за преобразования типа, так как divide даст десятичную дробь, ваш () находится не в том месте


Agarwal1984

Спасибо, но теперь вторая проблема заключается в том, когда я распаковываю файл, поэтому он получает ошибку:-
Не читал, что zip-файл.
Я использую этот код:-

строка zipToUnpack = @ "C:\" + файл;
string unpackDirectory = @ " C:\";
using (ZipFile zip1 = ZipFile. Read(zipToUnpack))
{
foreach (ZipEntry ze in zip1)
{
Зе.Экстракт(unpackDirectory, ExtractExistingFileAction.OverwriteSilently);
}
}

Philippe Mori

Напишите компилируемый код. Вы инвертируете int и iProgress.

Mycroft Holmes

Erk та же ошибка, что и OP, мое единственное оправдание, она была введена в ответ, а не скопирована из IDE.

Рейтинг:
0

OriginalGriff

Если вы получаете исключение деления на ноль в этом коде:

bytes += bytesRead;// don't forget to increment bytesRead !
int totalSize = (int)(fileSize) / 1000; // Kbytes
backgroundWorker1.ReportProgress((bytes / 1000) * 100 / totalSize, totalSize);
Тогда проблема должна быть в том, что totalSize равен нулю в последней строке: это означает, что fileSize меньше 1000.

Мы не можем исправить это для вас: мы не можем сделать файлы больше! Вам нужно проверить, где вы получаете размер файла с помощью отладчика, и либо получить в нем лучшее значение, либо (если оно правильное и ниже 1000) проверить его и вообще не делать деления.