Comment créer des archives 7-Zip à partir de mon application console C #? Je dois pouvoir extraire les archives en utilisant le programme régulier et largement disponible 7-Zip .
byte[]
. Lorsque j'écris le tableau byte[]
dans un fichier, je ne peux pas l'extraire à l'aide de 7-Zip (File.7z is not supported archive
).File.7z is not supported archive
).Si vous pouvez garantir que l'application 7-Zip sera installée (et dans le chemin) sur toutes les machines cibles, vous pouvez effectuer un déchargement en appelant l'application de ligne de commande 7z. Pas la solution la plus élégante mais c'est le moins de travail.
Exemple de cookie EggCafe 7Zip Ceci est un exemple (cookie zippé) avec le DLL de 7Zip.
CodePlex Wrapper .__ Ceci est un projet open source qui déforme la fonction de zipping de 7z.
SDK 7Zip Le SDK officiel de 7Zip (C, C++, C #, Java) <--- Ma suggestion
Bibliothèque .Net Zip de SharpDevelop.net
CodeProject exemple avec 7Zip
SharpZipLib Nombreuses compressions
SevenZipSharp est une autre solution. Crée des archives 7-Zip ...
Voici un exemple de travail complet utilisant le SDK SevenZip en C #.
Il écrira et lira les fichiers 7Zip standard créés par l’application Windows 7Zip.
PS. L'exemple précédent ne va jamais décompresser car il n'a jamais écrit les informations de propriété requises au début du fichier.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SevenZip.Compression.LZMA;
using System.IO;
using SevenZip;
namespace VHD_Director
{
class My7Zip
{
public static void CompressFileLZMA(string inFile, string outFile)
{
Int32 dictionary = 1 << 23;
Int32 posStateBits = 2;
Int32 litContextBits = 3; // for normal files
// UInt32 litContextBits = 0; // for 32-bit data
Int32 litPosBits = 0;
// UInt32 litPosBits = 2; // for 32-bit data
Int32 algorithm = 2;
Int32 numFastBytes = 128;
string mf = "bt4";
bool eos = true;
bool stdInMode = false;
CoderPropID[] propIDs = {
CoderPropID.DictionarySize,
CoderPropID.PosStateBits,
CoderPropID.LitContextBits,
CoderPropID.LitPosBits,
CoderPropID.Algorithm,
CoderPropID.NumFastBytes,
CoderPropID.MatchFinder,
CoderPropID.EndMarker
};
object[] properties = {
(Int32)(dictionary),
(Int32)(posStateBits),
(Int32)(litContextBits),
(Int32)(litPosBits),
(Int32)(algorithm),
(Int32)(numFastBytes),
mf,
eos
};
using (FileStream inStream = new FileStream(inFile, FileMode.Open))
{
using (FileStream outStream = new FileStream(outFile, FileMode.Create))
{
SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder();
encoder.SetCoderProperties(propIDs, properties);
encoder.WriteCoderProperties(outStream);
Int64 fileSize;
if (eos || stdInMode)
fileSize = -1;
else
fileSize = inStream.Length;
for (int i = 0; i < 8; i++)
outStream.WriteByte((Byte)(fileSize >> (8 * i)));
encoder.Code(inStream, outStream, -1, -1, null);
}
}
}
public static void DecompressFileLZMA(string inFile, string outFile)
{
using (FileStream input = new FileStream(inFile, FileMode.Open))
{
using (FileStream output = new FileStream(outFile, FileMode.Create))
{
SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder();
byte[] properties = new byte[5];
if (input.Read(properties, 0, 5) != 5)
throw (new Exception("input .lzma is too short"));
decoder.SetDecoderProperties(properties);
long outSize = 0;
for (int i = 0; i < 8; i++)
{
int v = input.ReadByte();
if (v < 0)
throw (new Exception("Can't Read 1"));
outSize |= ((long)(byte)v) << (8 * i);
}
long compressedSize = input.Length - input.Position;
decoder.Code(input, output, compressedSize, outSize, null);
}
}
}
public static void Test()
{
CompressFileLZMA("DiscUtils.pdb", "DiscUtils.pdb.7z");
DecompressFileLZMA("DiscUtils.pdb.7z", "DiscUtils.pdb2");
}
}
}
J'ai utilisé le SDK.
par exemple:
using SevenZip.Compression.LZMA;
private static void CompressFileLZMA(string inFile, string outFile)
{
SevenZip.Compression.LZMA.Encoder coder = new SevenZip.Compression.LZMA.Encoder();
using (FileStream input = new FileStream(inFile, FileMode.Open))
{
using (FileStream output = new FileStream(outFile, FileMode.Create))
{
coder.Code(input, output, -1, -1, null);
output.Flush();
}
}
}
string zipfile = @"E:\Folderx\NPPES.Zip";
string folder = @"E:\TargetFolderx";
ExtractFile(zipfile,folder);
public void ExtractFile(string source, string destination)
{
// If the directory doesn't exist, create it.
if (!Directory.Exists(destination))
Directory.CreateDirectory(destination);
//string zPath = ConfigurationManager.AppSettings["FileExtactorEXE"];
// string zPath = Properties.Settings.Default.FileExtactorEXE; ;
string zPath=@"C:\Program Files\7-Zip\7zG.exe";
try
{
ProcessStartInfo pro = new ProcessStartInfo();
pro.WindowStyle = ProcessWindowStyle.Hidden;
pro.FileName = zPath;
pro.Arguments = "x \"" + source + "\" -o" + destination;
Process x = Process.Start(pro);
x.WaitForExit();
}
catch (System.Exception Ex) { }
}
Il suffit d’installer 7 Zip à partir de la source et de transmettre le paramètre à la méthode.
Merci. S'il vous plaît, aimez la réponse.
Ce moyen le plus simple est de travailler avec des fichiers .Zip au lieu de .7z et d’utiliser Dot Net Zip
Lors du transfert de commandes 7Zip à Shell, il existe d'autres problèmes, tels que les privilèges utilisateur, un problème avec SevenZipSharp.
Private Function CompressFile(filename As String) As Boolean
Using Zip As New ZipFile()
Zip.AddFile(filename & ".txt", "")
Zip.Save(filename & ".Zip")
End Using
Return File.Exists(filename & ".Zip")
End Function
J'utilise ce code
string PZipPath = @"C:\Program Files\7-Zip\7z.exe";
string sourceCompressDir = @"C:\Test";
string targetCompressName = @"C:\Test\abc.Zip";
string CompressName = targetCompressName.Split('\\').Last();
string[] fileCompressList = Directory.GetFiles(sourceCompressDir, "*.*");
if (fileCompressList.Length == 0)
{
MessageBox.Show("No file in directory", "Important Message");
return;
}
string filetozip = null;
foreach (string filename in fileCompressList)
{
filetozip = filetozip + "\"" + filename + " ";
}
ProcessStartInfo pCompress = new ProcessStartInfo();
pCompress.FileName = PZipPath;
if (chkRequestPWD.Checked == true)
{
pCompress.Arguments = "a -tzip \"" + targetCompressName + "\" " + filetozip + " -mx=9" + " -p" + tbPassword.Text;
}
else
{
pCompress.Arguments = "a -tzip \"" + targetCompressName + "\" \"" + filetozip + "\" -mx=9";
}
pCompress.WindowStyle = ProcessWindowStyle.Hidden;
Process x = Process.Start(pCompress);
x.WaitForExit();
SharpCompress est à mon avis l’une des bibliothèques de compression les plus intelligentes du marché. Il prend en charge LZMA (7-Zip), est facile à utiliser et en développement actif.
Comme il prend déjà en charge le streaming LZMA, il ne supporte malheureusement, à l’heure de la rédaction, que la lecture des archives 7-Zip. MAIS l'écriture d'archive est sur leur liste de tâches (voir le readme). Pour les futurs lecteurs: Cochez pour obtenir le statut actuel ici: https://github.com/adamhathcock/sharpcompress/blob/master/FORMATS.md
Quelques informations de test supplémentaires sur le code @Orwellophile à l’aide d’un fichier texte de 17,9 Mo.
L'utilisation des valeurs de propriété dans l'exemple de code "tel quel" aura un impact négatif ÉNORANT sur les performances, cela prend 14,16 secondes .
Définissez les propriétés suivantes comme suit: 3,91 sec (entre autres, l’archive contiendra les mêmes informations sur le conteneur: vous pouvez extraire et tester le archive avec 7Zip mais il n'y a pas d'information de nom de fichier)
7Zip natif 2 secondes
CoderPropID[] propIDs = {
//CoderPropID.DictionarySize,
//CoderPropID.PosStateBits,
//CoderPropID.LitContextBits,
//CoderPropID.LitPosBits,
//CoderPropID.Algorithm,
//CoderPropID.NumFastBytes,
//CoderPropID.MatchFinder,
CoderPropID.EndMarker
};
object[] properties = {
//(Int32)(dictionary),
//(Int32)(posStateBits),
//(Int32)(litContextBits),
//(Int32)(litPosBits),
//(Int32)(algorithm),
//(Int32)(numFastBytes),
//mf,
eos
};
J'ai fait un autre test en utilisant 7Zip natif et un fichier de sauvegarde SQL de 1,2 Go (.bak)
7Zip (compression maximale): 1 minute
LZMA SDK (@Orwellophile avec la configuration de propriété ci-dessus): 12:26 min :
Fichier de sortie à peu près de la même taille.
Je suppose donc que j'utiliserai moi-même une solution basée sur le moteur c/c ++, i.a. soit appeler l'exécutable 7Zip à partir de c # ou utiliser --- (squid-box/SevenZipSharp , qui encapsule le fichier dll 7Zip c/c ++ et semble être le dernier fork de SevenZipSharp. Je n'ai pas testé l'emballage, mais j'espère que c'est aussi performant que le 7Zip natif. Mais j'espère que cela donnera la possibilité de compresser le flux, ce que vous ne pouvez évidemment pas faire si vous appelez directement l'exe. Sinon, je suppose qu’il n’ya aucun avantage à appeler l’exe. Le wrapper a quelques dépendances supplémentaires donc il ne rendra pas votre projet publié "plus propre".
En passant, il semble que l’équipe .Net Core envisage d’implémenter LZMA dans la classe system.io dans .Core ver. 5, ce serait génial!
(Je sais que c'est en quelque sorte un commentaire et non une réponse, mais pour pouvoir fournir l'extrait de code, il ne peut s'agir d'un commentaire)
Installez le paquet NuGet appelé SevenZipSharp.Interop
Ensuite:
SevenZipBase.SetLibraryPath(@".\x86\7z.dll");
var compressor = new SevenZip.SevenZipCompressor();
var filesToCompress = Directory.GetFiles(@"D:\data\");
compressor.CompressFiles(@"C:\archive\abc.7z", filesToCompress);