[英]How to create Subfolder.Zip file from Folder.Zip in C#
我正在嘗試使用 .NETCore LAMBDA function 從 Build Artifacts 創建一些包,由於存儲限制 LAMBDA 臨時存儲僅為 512,因此面臨一些問題我的工件(Zip 文件大小為 300MB)結構是
./scripts.bat
./scripts2.yml
./Env/Svr1/somefile.txt
./Env/Svr1/somefolder/somefile.txt
./Env/Svr1/somefolder/someotherfolder/somefile.txt
任務是將scripts.bat和scripts2.yml復制到./Env/Svr1/和zip的Svr1(不包括./Env/Svr2/..etc中的其他文件夾)的內容為./Svr1.zip在根級別沒有解壓縮整個 zip,因為存儲是受限的。
var tempPath = @"/tmp/";
using (var file = File.OpenRead(tempPath+ "MyZipFile.zip"))
{
using (var zipFile = new ZipArchive(file, ZipArchiveMode.Read, true))
{
var ymlConfigs = zipFile.Entries.Select(f => f.Name).Where(en => en.EndsWith(".yml"));
var batFiles = zipFile.Entries.Select(f => f.Name).Where(en => en.EndsWith(".bat"));
var svr1Folder = zipFile.Entries.Select(folder => folder.FullName).Where(name => name.StartsWith("Env/Svr1"));
//add yml files to package
foreach (var ymlfile in ymlConfigs)
{
svr1Folder.Concat(new[] { ymlfile });
}
//add bat files to package
foreach (var batfile in batFiles)
{
svr1Folder.Concat(new[] { batfile });
}
//create zip package
var newZip = ZipFile.Open(tempPath + "Svr1", ZipArchiveMode.Update);
foreach (var item in svr1Folder)
{
newZip.CreateEntryFromFile(item, Path.GetFileName(item), CompressionLevel.Optimal);
//Error Could not find a part of the path as its looking for Item in Debug folder ..\bin\Debug\netcoreapp3.1\Env\Svr1\somefile.txt where as my item is in ./tmp/MyZipFile.zip
}
}
}
我設法找到一個解決方案,將 zip 文件讀取為 Stream 並創建一個新的 zip 文件,其中包含空文件夾並從原始文件中添加所需的條目。
using (FileStream zipToOpen = new FileStream(tempPath + folder + ".zip",
FileMode.Open))
{
using (ZipArchive archive = new ZipArchive(zipToOpen,
ZipArchiveMode.Update))
{
foreach (var item in svr1Package)
{
var splitString = item.FullName.Split("/");
var path = String.Join("/", item.FullName.Split("/").Skip(2));
if (!String.IsNullOrEmpty(path))
{
var temp = path.Substring(0,path.LastIndexOf("/"));
var outputpath = Path.Combine(tempPath, temp);
var readEntry = archive.CreateEntry(path);//creates file with this
//name
//read data from original item and load in memory
var inputStream = item.Open();
byte[] data = null;
byte[] buffer = new byte[16 * 1024];
using (MemoryStream memoryStream = new MemoryStream())
{
int read;
while ((read = inputStream.Read(buffer, 0,buffer.Length)) > 0)
{
memoryStream.Write(buffer, 0, read);
}
data = memoryStream.ToArray();
}
//write back data to newZip file
using (BinaryWriter writer = new BinaryWriter(readEntry.Open()))
{
writer.Write(data);
}
}
else //these are just txt or bat files copy as it is
{
if ((item.FullName.StartsWith("appspec_sv1")) ||
(item.FullName.StartsWith("appspec_sv2")))
{
var readEntry = archive.CreateEntry("appspec.yml");
StringBuilder stringBuilder;
using (StreamReader reader = new StreamReader(item.Open()))
{
stringBuilder = new StringBuilder(reader.ReadToEnd());
}
using (StreamWriter writer = new StreamWriter(readEntry.Open()))
{
writer.Write(stringBuilder);
}
}
else
{
var readEntry = archive.CreateEntry(item.FullName);
StringBuilder stringBuilder;
using (StreamReader reader = new StreamReader(item.Open()))
{
stringBuilder = new StringBuilder(reader.ReadToEnd());
}
using (StreamWriter writer = new StreamWriter(readEntry.Open()))
{
writer.Write(stringBuilder);
}
}
}
}
transferUtility.Upload(tempPath + folder + ".zip",bucketName,
outputPrefix + folder + ".zip");
}
我已經回答了如何在 .NET 中創建 zip 之前的這篇文章在 ZipArchive 中創建目錄 C#.Net 4.5我認為你仍然可以在 dotnet 核心中應用。
此外,如果您在類 unix 環境中運行應用程序,則可以簡單地使用 zip 命令,該命令可能在 AWS 上可用
干杯,香草
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.