Сжатие одного файла с помощью С#

Я использую .NET 4.5, а класс ZipFile отлично работает, если я пытаюсь закрепить весь каталог с помощью "CreateFromDirectory". Тем не менее, я только хочу закрепить один файл в каталоге. Я попытался указать на определенный файл (folder\data.txt), но это не работает. Я считал класс ZipArchive, поскольку он имеет метод CreateEntryFromFile, но, похоже, это позволяет вам создать запись в существующий файл.

Нет ли способа просто закрепить один файл без создания пустого zip файла (который имеет свои проблемы), а затем с помощью метода "CreateEntryFromFile" ZipArchiveExtension?

** Это также предполагает, что я работаю над корпоративной программой, которая в настоящий момент не может использовать сторонние надстройки.

пример из: http://msdn.microsoft.com/en-us/library/ms404280%28v=vs.110%29.aspx

        string startPath = @"c:\example\start";
        string zipPath = @"c:\example\result.zip";
        string extractPath = @"c:\example\extract";

        ZipFile.CreateFromDirectory(startPath, zipPath);

        ZipFile.ExtractToDirectory(zipPath, extractPath);

Но если startPath должен был быть @"c:\example\start\myFile.txt;", он выдавал бы ошибку, если каталог недействителен.

Ответ 1

Самый простой способ получить эту работу - использовать временную папку.

ДЛЯ ЗАРЕГИСТРИРОВАНИЯ:

  • Создать временную папку
  • Переместить файл в папку
  • Почтовая папка
  • Удалить папку

ЗА UNZIPPING:

  • Распаковать архив
  • Переместить файл из папки temp в ваше местоположение.
  • Удалить временную папку

Ответ 2

Используйте CreateEntryFromFile из архива и используйте файл или поток памяти:

Использование фильтра, если вы хорошо создаете zip файл и затем добавляете к нему:

using (FileStream fs = new FileStream(@"C:\Temp\output.zip",FileMode.Create))
using (ZipArchive arch = new ZipArchive(fs, ZipArchiveMode.Create))
{
    arch.CreateEntryFromFile(@"C:\Temp\data.xml", "data.xml");
}

Или, если вам нужно сделать все в памяти и записать файл после его завершения, используйте поток памяти:

using (MemoryStream ms = new MemoryStream())
using (ZipArchive arch = new ZipArchive(ms, ZipArchiveMode.Create))
{
    arch.CreateEntryFromFile(@"C:\Temp\data.xml", "data.xml");
}

Затем вы можете записать MemoryStream в файл.

using (FileStream file = new FileStream("file.bin", FileMode.Create, System.IO.FileAccess.Write)) {
   byte[] bytes = new byte[ms.Length];
   ms.Read(bytes, 0, (int)ms.Length);
   file.Write(bytes, 0, bytes.Length);
   ms.Close();
}

Ответ 3

Использование файла (или любого) потока:

using (var zip = ZipFile.Open("file.zip", ZipArchiveMode.Create))
{
    var entry = zip.CreateEntry("file.txt");
    entry.LastWriteTime = DateTimeOffset.Now;

    using (var stream= File.OpenRead(@"c:\path\to\file.txt"))
    using (var entryStream = entry.Open())
        stream.CopyTo(entryStream);
}

или briefer:

// reference System.IO.Compression
using (var zip = ZipFile.Open("file.zip", ZipArchiveMode.Create))
    zip.CreateEntryFromFile("file.txt", "file.txt");

убедитесь, что вы добавили ссылки на System.IO.Compression

Ответ 4

В .NET существует довольно много способов решить проблему, для одного файла. Если вы не хотите изучать все, что угодно, вы можете получить абстрактную библиотеку, такую ​​как SharpZipLib (долгостоящая библиотека с открытым исходным кодом), sevenzipsharp (требует 7zip libs внизу) или DotNetZip.

Ответ 5

просто используйте следующий код для сжатия файла.

public void Compressfile()
        {
             string fileName = "Text.txt";
             string sourcePath = @"C:\SMSDBBACKUP";
             DirectoryInfo di = new DirectoryInfo(sourcePath);
             foreach (FileInfo fi in di.GetFiles())
             {
                 //for specific file 
                 if (fi.ToString() == fileName)
                 {
                     Compress(fi);
                 }
             } 
        }

public static void Compress(FileInfo fi)
        {
            // Get the stream of the source file.
            using (FileStream inFile = fi.OpenRead())
            {
                // Prevent compressing hidden and 
                // already compressed files.
                if ((File.GetAttributes(fi.FullName)
                    & FileAttributes.Hidden)
                    != FileAttributes.Hidden & fi.Extension != ".gz")
                {
                    // Create the compressed file.
                    using (FileStream outFile =
                                File.Create(fi.FullName + ".gz"))
                    {
                        using (GZipStream Compress =
                            new GZipStream(outFile,
                            CompressionMode.Compress))
                        {
                            // Copy the source file into 
                            // the compression stream.
                            inFile.CopyTo(Compress);

                            Console.WriteLine("Compressed {0} from {1} to {2} bytes.",
                                fi.Name, fi.Length.ToString(), outFile.Length.ToString());
                        }
                    }
                }
            }
        }

    }