Разархивирование файла ошибки - PullRequest
1 голос
/ 04 декабря 2008

Я использую .net-библиотеку SharpZipLib с открытым исходным кодом из www.icsharpcode.net

Моя цель - разархивировать XML-файл и прочитать его в наборе данных. Однако я получаю следующую ошибку при чтении файла в наборе данных: «Данные на корневом уровне недействительны. Строка 1, позиция 1». Я полагаю, что происходит, когда код распаковки не выпускает файл по следующим причинам.

1.) Если я разархивирую файл и выйду из приложения. Когда я перезагружаю приложение, я могу прочитать распакованный файл в наборе данных. 2.) Если я прочитал файл xml сразу после его записи (без архивирования), он работает нормально.
3.) Если я запишу набор данных в xml, разархивирую его, разархивирую, а затем попытаюсь прочитать его обратно, я получу исключение.

Код ниже довольно прост. UnZipFile вернет имя файла, только что распакованного. Прямо под этим вызовом находится вызов, чтобы прочитать его в наборе данных. Переменная fileToRead - это полный путь к вновь распакованному XML-файлу.

string fileToRead = UnZipFile(filepath, DOViewerUploadStoreArea);
ds.ReadXml(fileToRead )

private string UnZipFile(string file, string dirToUnzipTo)
{

       string unzippedfile = "";

        try
        {
            ZipInputStream s = new ZipInputStream(File.OpenRead(file));
            ZipEntry myEntry;
            string tmpEntry = String.Empty;
            while ((myEntry = s.GetNextEntry()) != null)
            {
                string directoryName = dirToUnzipTo;
                string fileName = Path.GetFileName(myEntry.Name);
                string fileWDir = directoryName + fileName;
                unzippedfile = fileWDir;

                FileStream streamWriter = File.Create(fileWDir);
                int size = 4096;
                byte[] data = new byte[4096];
                while (true)
                {
                    size = s.Read(data, 0, data.Length);
                    if (size > 0) { streamWriter.Write(data, 0, size); }
                    else { break; }
                }
                streamWriter.Close();
            }
            s.Close();
        }
        catch (Exception ex)
        {
            LogStatus.WriteErrorLog(ex, "ERROR", "DOViewer.UnZipFile");

        }
        return (unzippedfile);
    }

Ответы [ 3 ]

1 голос
/ 04 декабря 2008

Ну, как выглядит окончательный файл? (по сравнению с оригиналом). Вы не показываете почтовый индекс, который может быть частью головоломки, особенно если вы частично проглотили исключение.

Я бы также попробовал убедиться, что все IDisposable равно Dispose() d, в идеале через using; также - если проблема связана с построением пути, используйте Path.Combine. И обратите внимание, что если myEntry.Name содержит подкаталоги, вам нужно будет создать их вручную.

Вот что у меня есть - работает для распаковки ICSharpCode.SharpZipLib.dll:

    private string UnZipFile(string file, string dirToUnzipTo)
    {

        string unzippedfile = "";

        try
        {
            using(Stream inStream = File.OpenRead(file))
            using (ZipInputStream s = new ZipInputStream(inStream))
            {
                ZipEntry myEntry;
                byte[] data = new byte[4096];
                while ((myEntry = s.GetNextEntry()) != null)
                {
                    string fileWDir = Path.Combine(dirToUnzipTo, myEntry.Name);
                    string dir = Path.GetDirectoryName(fileWDir);
                    // note only supports a single level of sub-directories...
                    if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
                    unzippedfile = fileWDir; // note; returns last file if multiple

                    using (FileStream outStream = File.Create(fileWDir))
                    {
                        int size;
                        while ((size = s.Read(data, 0, data.Length)) > 0)
                        {
                            outStream.Write(data, 0, size);
                        }
                        outStream.Close();
                    }
                }
                s.Close();
            }

        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);

        }
        return (unzippedfile);
    }

Также может быть проблема в коде, который пишет zip, или в коде, который читает сгенерированный файл.

0 голосов
/ 15 мая 2009

Это намного проще сделать с DotNetZip.

using (ZipFile zip = ZipFile.Read(ExistingZipFile))
{
     zip.ExtractAll(TargetDirectory);       
}

Если вы хотите решить, какие файлы извлекать ....

using (ZipFile zip = ZipFile.Read(ExistingZipFile))
{
    foreach (ZipEntry e in zip)
    {
        if (wantThisFile(e.FileName)) e.Extract(TargetDirectory);
    }
}

Если вы хотите перезаписать существующие файлы во время извлечения:

using (ZipFile zip = ZipFile.Read(ExistingZipFile))
{
     zip.ExtractAll(TargetDirectory, ExtractExistingFileAction.OverwriteSilently);
}

Или, чтобы извлечь защищенные паролем записи:

using (ZipFile zip = ZipFile.Read(ExistingZipFile))
{
     zip.Password = "Shhhh, Very Secret!";
     zip.ExtractAll(TargetDirectory, ExtractExistingFileAction.OverwriteSilently);
}
0 голосов
/ 04 декабря 2008

Я сравнил оригинал с конечным использованием TextPad, и они идентичны. Также я переписал код, чтобы воспользоваться преимуществами использования. Вот код Кажется, моя проблема связана с блокировкой файлов или чем-то еще. Если я разархивирую файл и выйду из приложения, то запустится, он прочитает find.

private string UnZipFile(string file, string dirToUnzipTo)
    {
        string unzippedfile = "";

        try
        {
            using (ZipInputStream s = new ZipInputStream(File.OpenRead(file)))
            {

                ZipEntry theEntry;
                while ((theEntry = s.GetNextEntry()) != null)
                {
                    string directoryName = dirToUnzipTo;
                    string fileName = Path.GetFileName(theEntry.Name);
                    string fileWDir = directoryName + fileName;
                    unzippedfile = fileWDir;

                    if (fileName != String.Empty)
                    {
                        using (FileStream streamWriter = File.Create(fileWDir))
                        {
                            int size = 2048;
                            byte[] data = new byte[2048];
                            while (true)
                            {
                                size = s.Read(data, 0, data.Length);
                                if (size > 0)
                                {
                                    streamWriter.Write(data, 0, size);
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            LogStatus.WriteErrorLog(ex, "ERROR", "DOViewer.UnZipFile");

        }
        return (unzippedfile);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...