web-dev-qa-db-fra.com

Compresser un seul fichier en utilisant C #

J'utilise .NET 4.5 et la classe ZipFile fonctionne très bien si j'essaie de compresser un répertoire entier avec "CreateFromDirectory". Cependant, je veux seulement compresser un fichier dans le répertoire. J'ai essayé de pointer vers un fichier spécifique (dossier\data.txt), mais cela ne fonctionne pas. J'ai considéré la classe ZipArchive car elle possède une méthode "CreateEntryFromFile", mais il semble que cela ne vous permette que de créer une entrée dans un fichier existant. 

N'y a-t-il aucun moyen de simplement compresser un fichier sans créer un fichier zip vide (qui a ses problèmes) et d'utiliser ensuite la méthode "CreateEntryFromFile" de ZipArchiveExtension?

** Cela suppose également que je travaille sur un programme d'entreprise qui ne peut pas utiliser de modules complémentaires tiers pour le moment.

exemple de: 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);

Mais si startPath devait être @"c:\example\start\myFile.txt;", le répertoire serait invalide.

26
user3362735

Le moyen le plus simple pour que cela fonctionne est d'utiliser un dossier temporaire.

POUR ZIPPING:

  1. Créer un dossier temporaire
  2. Déplacer le fichier dans un dossier
  3. Dossier compressé
  4. Supprimer le dossier

POUR UNZIPPING:

  1. Décompresser l'archive
  2. Déplacer le fichier du dossier temporaire vers votre emplacement
  3. Supprimer le dossier temporaire
5
AlexanderBrevig

Utilisez le CreateEntryFromFile off d'une archive et utilisez un fichier ou un flux de mémoire:

Utiliser un filestream si vous voulez créer le fichier Zip et l’ajouter ensuite:

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");
}

Ou si vous devez tout faire en mémoire et écrire le fichier une fois que c'est fait, utilisez un flux de mémoire:

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

Ensuite, vous pouvez écrire le MemoryStream dans un fichier .

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();
}
36
John Koerner

Utilisation d'un fichier (ou de tout flux):

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);
}

ou plus bref:

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

assurez-vous d’ajouter des références à System.IO.Compression

Mettre à jour

Consultez également la nouvelle documentation de l’API dotnet pour ZipFile et ZipArchive aussi. Il y a quelques exemples ici. Il existe également un avertissement sur le fait de référencer System.IO.Compression.FileSystem pour utiliser ZipFile.

Pour utiliser la classe ZipFile, vous devez référencer le fichier System.IO.Compression.FileSystem Assemblage dans votre projet.

20
ziya

utilisez simplement le code suivant pour compresser un fichier.

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());
                        }
                    }
                }
            }
        }

    }
0
Jeetendra Negi

En .NET, il existe plusieurs moyens de résoudre le problème, pour un seul fichier. Si vous ne voulez pas tout apprendre, vous pouvez vous procurer une bibliothèque abstraite, telle que SharpZipLib (bibliothèque open source de longue date), sevenzipsharp (requiert 7Zip libs dessous) ou DotNetZip.

0
Gregory A Beamer