これは重複していないと確信しているので、しばらくお待ちください。
サードパーティのライブラリを使用せずに(Windowsで)ファイルをZip圧縮(C#)するにはどうすればよいですか?ネイティブのWindows呼び出しなどが必要です。私はプロセスを開始するという考えを本当に嫌いますが、絶対にやらなければならない場合はそうします。 PInovkeコールの方がはるかに良いでしょう。
それに失敗したら、私が本当に達成しようとしていることをお話ししましょう。ユーザーに1回のリクエストでドキュメントのコレクションをダウンロードさせる機能が必要です。これを達成する方法に関するアイデアはありますか?
.NET 3.5を使用していますか? ZipPackage
クラスと関連クラスを使用できます。追加するファイルごとにMIMEタイプが必要なため、ファイルリストを圧縮するだけではありません。それはあなたが望むことをするかもしれません。
現在、これらのクラスを同様の問題に使用して、複数の関連ファイルをダウンロード用の単一ファイルにアーカイブしています。ファイル拡張子を使用して、ダウンロードファイルをデスクトップアプリに関連付けます。私たちが遭遇した小さな問題の1つは、クライアント側のコードで開くことができないため、7-Zipなどのサードパーティツールを使用してZipファイルを作成することができないことです-ZipPackageは、コンテンツタイプを記述する隠しファイルを追加します各コンポーネントファイル。そのコンテンツタイプファイルが見つからない場合、Zipファイルを開くことができません。
サードパーティのライブラリを使用せずに(Windowsで)ファイルをZip圧縮(C#)するにはどうすればよいですか?
4.5+フレームワークを使用している場合、 ZipArchive および ZipFile クラスがあります。
using (ZipArchive Zip = ZipFile.Open("test.Zip", ZipArchiveMode.Create))
{
Zip.CreateEntryFromFile(@"c:\something.txt", "data/path/something.txt");
}
以下に参照を追加する必要があります。
Net46を対象とする.NET Coreの場合、次の依存関係を追加する必要があります。
Project.jsonの例:
"dependencies": {
"System.IO.Compression": "4.1.0",
"System.IO.Compression.ZipFile": "4.0.1"
},
"frameworks": {
"net46": {}
}
.NET Core 2.0では、単純なusingステートメントを追加するだけで十分です。
私は同じ状況にあり、サードパーティのライブラリではなく.NETを望んでいました。前述の別のポスターとして、ZipPackageクラス(.NET 3.5で導入)を使用するだけでは十分ではありません。 ZipPackageが機能するためには、アーカイブに追加する必要がある追加のファイルがあります。このファイルを追加すると、結果のZipパッケージをWindowsエクスプローラーから直接開くことができます-問題ありません。
必要なことは、[Content_Types] .xmlファイルをアーカイブのルートに追加することです。これには、含めるファイル拡張子ごとに「デフォルト」ノードを指定します。追加したら、Windowsエクスプローラーからパッケージを参照するか、プログラムで解凍してその内容を読み取ることができます。
[Content_Types] .xmlファイルの詳細については、次を参照してください。 http://msdn.Microsoft.com/en-us/magazine/cc163372.aspx
[Content_Types] .xml(正確な名前を付ける必要があります)ファイルのサンプルを次に示します。
<?xml version="1.0" encoding="utf-8" ?>
<Types xmlns=
"http://schemas.openxmlformats.org/package/2006/content-types">
<Default Extension="xml" ContentType="text/xml" />
<Default Extension="htm" ContentType="text/html" />
<Default Extension="html" ContentType="text/html" />
<Default Extension="rels" ContentType=
"application/vnd.openxmlformats-package.relationships+xml" />
<Default Extension="jpg" ContentType="image/jpeg" />
<Default Extension="png" ContentType="image/png" />
<Default Extension="css" ContentType="text/css" />
</Types>
そして、Zipファイルを作成するためのC#:
var zipFilePath = "c:\\myfile.Zip";
var tempFolderPath = "c:\\unzipped";
using (Package package = ZipPackage.Open(zipFilePath, FileMode.Open, FileAccess.Read))
{
foreach (PackagePart part in package.GetParts())
{
var target = Path.GetFullPath(Path.Combine(tempFolderPath, part.Uri.OriginalString.TrimStart('/')));
var targetDir = target.Remove(target.LastIndexOf('\\'));
if (!Directory.Exists(targetDir))
Directory.CreateDirectory(targetDir);
using (Stream source = part.GetStream(FileMode.Open, FileAccess.Read))
{
source.CopyTo(File.OpenWrite(target));
}
}
}
注意:
private static string CompressFile(string sourceFileName)
{
using (ZipArchive archive = ZipFile.Open(Path.ChangeExtension(sourceFileName, ".Zip"), ZipArchiveMode.Create))
{
archive.CreateEntryFromFile(sourceFileName, Path.GetFileName(sourceFileName));
}
return Path.ChangeExtension(sourceFileName, ".Zip");
}
.NET 2.0アプリでは、 SharpZipLib を使用しました。使いやすく、オープンソース。
Simon McKenzieの答え この質問に対する に基づいて、次のようなメソッドのペアを使用することをお勧めします。
public static void ZipFolder(string sourceFolder, string zipFile)
{
if (!System.IO.Directory.Exists(sourceFolder))
throw new ArgumentException("sourceDirectory");
byte[] zipHeader = new byte[] { 80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
using (System.IO.FileStream fs = System.IO.File.Create(zipFile))
{
fs.Write(zipHeader, 0, zipHeader.Length);
}
dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
dynamic source = shellApplication.NameSpace(sourceFolder);
dynamic destination = shellApplication.NameSpace(zipFile);
destination.CopyHere(source.Items(), 20);
}
public static void UnzipFile(string zipFile, string targetFolder)
{
if (!System.IO.Directory.Exists(targetFolder))
System.IO.Directory.CreateDirectory(targetFolder);
dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
dynamic compressedFolderContents = shellApplication.NameSpace(zipFile).Items;
dynamic destinationFolder = shellApplication.NameSpace(targetFolder);
destinationFolder.CopyHere(compressedFolderContents);
}
}
Windowsでできることのように見えます this ...
残念ながら、サードパーティのコンポーネントに移動しない限り、別のプロセスを開始することはできないと思います。
次の4つの関数をプロジェクトに追加します。
public const long BUFFER_SIZE = 4096;
public static void AddFileToZip(string zipFilename, string fileToAdd)
{
using (Package Zip = global::System.IO.Packaging.Package.Open(zipFilename, FileMode.OpenOrCreate))
{
string destFilename = ".\\" + Path.GetFileName(fileToAdd);
Uri uri = PackUriHelper.CreatePartUri(new Uri(destFilename, UriKind.Relative));
if (Zip.PartExists(uri))
{
Zip.DeletePart(uri);
}
PackagePart part = Zip.CreatePart(uri, "", CompressionOption.Normal);
using (FileStream fileStream = new FileStream(fileToAdd, FileMode.Open, FileAccess.Read))
{
using (Stream dest = part.GetStream())
{
CopyStream(fileStream, dest);
}
}
}
}
public static void CopyStream(global::System.IO.FileStream inputStream, global::System.IO.Stream outputStream)
{
long bufferSize = inputStream.Length < BUFFER_SIZE ? inputStream.Length : BUFFER_SIZE;
byte[] buffer = new byte[bufferSize];
int bytesRead = 0;
long bytesWritten = 0;
while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) != 0)
{
outputStream.Write(buffer, 0, bytesRead);
bytesWritten += bytesRead;
}
}
public static void RemoveFileFromZip(string zipFilename, string fileToRemove)
{
using (Package Zip = global::System.IO.Packaging.Package.Open(zipFilename, FileMode.OpenOrCreate))
{
string destFilename = ".\\" + fileToRemove;
Uri uri = PackUriHelper.CreatePartUri(new Uri(destFilename, UriKind.Relative));
if (Zip.PartExists(uri))
{
Zip.DeletePart(uri);
}
}
}
public static void Remove_Content_Types_FromZip(string zipFileName)
{
string contents;
using (ZipFile zipFile = new ZipFile(File.Open(zipFileName, FileMode.Open)))
{
/*
ZipEntry startPartEntry = zipFile.GetEntry("[Content_Types].xml");
using (StreamReader reader = new StreamReader(zipFile.GetInputStream(startPartEntry)))
{
contents = reader.ReadToEnd();
}
XElement contentTypes = XElement.Parse(contents);
XNamespace xs = contentTypes.GetDefaultNamespace();
XElement newDefExt = new XElement(xs + "Default", new XAttribute("Extension", "sab"), new XAttribute("ContentType", @"application/binary; modeler=Acis; version=18.0.2application/binary; modeler=Acis; version=18.0.2"));
contentTypes.Add(newDefExt);
contentTypes.Save("[Content_Types].xml");
zipFile.BeginUpdate();
zipFile.Add("[Content_Types].xml");
zipFile.CommitUpdate();
File.Delete("[Content_Types].xml");
*/
zipFile.BeginUpdate();
try
{
zipFile.Delete("[Content_Types].xml");
zipFile.CommitUpdate();
}
catch{}
}
}
そして、これらを次のように使用します。
foreach (string f in UnitZipList)
{
AddFileToZip(zipFile, f);
System.IO.File.Delete(f);
}
Remove_Content_Types_FromZip(zipFile);