어떻게 C\#로 압축 파일 을 실현 합 니까?
장면,파일 이 비교적 클 수 있 으 므 로 업로드 와 다운로드 등 압축 전송 이 필요 합 니 다.
/// <summary>
///
/// </summary>
/// <param name="sourceFile"> </param>
/// <param name="zipedFile">zip </param>
/// <param name="blockSize"> </param>
/// <param name="compressionLevel"> </param>
public static void ZipFile(string sourceFile, string zipedFile, int blockSize = 1024, int compressionLevel = 6)
{
if (!File.Exists(sourceFile))
{
throw new System.IO.FileNotFoundException("The specified file " + sourceFile + " could not be found.");
}
var fileName = System.IO.Path.GetFileNameWithoutExtension(sourceFile);
FileStream streamToZip = new FileStream(sourceFile, FileMode.Open, FileAccess.Read);
FileStream zipFile = File.Create(zipedFile);
ZipOutputStream zipStream = new ZipOutputStream(zipFile);
ZipEntry zipEntry = new ZipEntry(fileName);
zipStream.PutNextEntry(zipEntry);
// 、 、 、 、 、 0-9
zipStream.SetLevel(compressionLevel);
byte[] buffer = new byte[blockSize];
int size = streamToZip.Read(buffer, 0, buffer.Length);
zipStream.Write(buffer, 0, size);
try
{
while (size < streamToZip.Length)
{
int sizeRead = streamToZip.Read(buffer, 0, buffer.Length);
zipStream.Write(buffer, 0, sizeRead);
size += sizeRead;
}
}
catch (Exception ex)
{
throw ex;
}
zipStream.Finish();
zipStream.Close();
streamToZip.Close();
}
설명:26 줄,blocksize 는 캐 시 영역 크기 입 니 다.너무 크게 설정 할 수 없습니다.너무 크 면 이상 을 보고 할 수 있 습 니 다.26-38 줄,파일 을 FileStream 흐름 을 통 해 버퍼 에 읽 고 Zip Output Stream 흐름 에 기록 합 니 다.두 개의 파이프,하 나 는 읽 고,다른 하 나 는 쓰 고,중간 은 버퍼 이 며,그들의 작업 방식 은 동기 화 방식 이 라 고 상상 할 수 있다.다른 방식 으로 일 할 수 있 는 지 생각해 보 세 요.읽 는 파 이 프 는 읽 기만 하고 쓴 파 이 프 는 쓰기 만 할 수 있 습 니까?만약 에 이런 장면 이 라면 읽 는 것 이 매우 빠 르 고 쓰 는 것 이 비교적 느리다.예 를 들 어 로 컬 쓰기 가 아니 라 네트워크 를 통 해 전송 해 야 하기 때문에 비동기 적 인 방식 을 고려 할 수 있다.어떻게 하면 독자 가 스스로 개조 할 수 있 습 니까?중요 한 것 은 흐름 은 순서 가 있 기 때문에 순서 의 정확성 을 확보 하면 된다.다 중 파일 압축
이런 장면 도 비교적 많이 볼 수 있 는데 단일 파일 의 압축 과 유사 하 다.단지 몇 번 더 순환 하 는 것 일 뿐이다.
/// <summary>
///
/// </summary>
/// <param name="zipfile">zip </param>
/// <param name="filenames"> </param>
/// <param name="password"> </param>
public void ZipFiles(string zipfile, string[] filenames, string password = "")
{
ZipOutputStream s = new ZipOutputStream(System.IO.File.Create(zipfile));
s.SetLevel(6);
if (password != "")
s.Password = Md5Help.Encrypt(password);
foreach (string file in filenames)
{
//
FileStream fs = File.OpenRead(file);
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
var name = Path.GetFileName(file);
ZipEntry entry = new ZipEntry(name);
entry.DateTime = DateTime.Now;
entry.Size = fs.Length;
fs.Close();
s.PutNextEntry(entry);
s.Write(buffer, 0, buffer.Length);
}
s.Finish();
s.Close();
}
설명:21 줄,버퍼 크기 가 파일 크기 이기 때문에 한 번 에 읽 고 쓰 지 않 았 습 니 다.이런 상황 에서 단일 파일 은 1G 를 초과 하 는 것 과 같이 너무 크 면 안 된다.14 줄,압축 패키지 에 비밀 번 호 를 설정 할 수 있 습 니 다.MD5 생 성 방법 은 다음 과 같 습 니 다.
public class Md5Help
{
/// <summary>
///32 MD5
/// </summary>
/// <param name="str"> </param>
/// <returns></returns>
public static string Encrypt(string str)
{
MD5 md5 = new MD5CryptoServiceProvider();
byte[] encryptdata = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
return Convert.ToBase64String(encryptdata);
}
}
3.다 중 파일 비동기 압축위 에서 동기 화 된 압축 의 전 제 는 파일 이 크 지 않 고 파일 수가 많 지 않다 고 가정 하 는 것 이다.그러나 현실 은 파일 만 크 지 않 고 파일 수가 많다 는 것 이다.이런 상황 에 서 는 비동기 적 인 방법 을 고려 해 야 한다.그렇지 않 으 면 메 인 스 레 드 를 막 을 것 이다.바로 우리 가 평소에 말 하 는 카드 죽음 이다.
/// <summary>
/// zip
/// </summary>
/// <param name="zipfile"> </param>
/// <param name="filenames"> </param>
public static async void ZipFilesAsync(string zipfile, string[] filenames)
{
await Task.Run(() =>
{
ZipOutputStream s = null;
try
{
s = new ZipOutputStream(System.IO.File.Create(zipfile));
s.SetLevel(6); // 0 - store only to 9 - means best compression
foreach (string file in filenames)
{
//
FileStream fs = System.IO.File.OpenRead(file);
var name = Path.GetFileName(file);
ZipEntry entry = new ZipEntry(name);
entry.DateTime = DateTime.Now;
entry.Size = fs.Length;
s.PutNextEntry(entry);
// 1G
long blockSize = 51200;
var size = (int)fs.Length;
var oneG = 1024 * 1024 * 1024;
if (size > oneG)
{
blockSize = oneG;
}
byte[] buffer = new byte[blockSize];
size = fs.Read(buffer, 0, buffer.Length);
s.Write(buffer, 0, size);
while (size < fs.Length)
{
int sizeRead = fs.Read(buffer, 0, buffer.Length);
s.Write(buffer, 0, sizeRead);
size += sizeRead;
}
s.Flush();
fs.Close();
}
}
catch (Exception ex)
{
Console.WriteLine(" :" + ex.Message);
}
finally
{
s?.Finish();
s?.Close();
}
});
}
압축 파일실제 응용 프로그램 에 서 는 파일 과 폴 더 를 함께 압축 하기 때문에 이 경우 아예 압축 할 물건 을 모두 폴 더 에 넣 고 압축 한다.
주 방법 은 다음 과 같다.
/// <summary>
/// zip
/// </summary>
/// <param name="zipfile"> </param>
/// <param name="sourceFolder"> </param>
/// <param name="filenames"> </param>
public static async void ZipFolderAsync(string zipfile, string sourceFolder, string[] filenames)
{
await Task.Run(() =>
{
ZipOutputStream s = null;
try
{
s = new ZipOutputStream(System.IO.File.Create(zipfile));
s.SetLevel(6); // 0 - store only to 9 - means best compression
CompressFolder(sourceFolder, s, sourceFolder);
}
catch (Exception ex)
{
Console.WriteLine(" :" + ex.Message);
}
finally
{
s?.Finish();
s?.Close();
}
});
}
압축 의 핵심 방법:
/// <summary>
///
/// </summary>
/// <param name="source"> </param>
/// <param name="s">ZipOutputStream </param>
/// <param name="parentPath"> source </param>
public static void CompressFolder(string source, ZipOutputStream s, string parentPath)
{
string[] filenames = Directory.GetFileSystemEntries(source);
foreach (string file in filenames)
{
if (Directory.Exists(file))
{
CompressFolder(file, s, parentPath); //
}
else
{
using (FileStream fs = System.IO.File.OpenRead(file))
{
var writeFilePath = file.Replace(parentPath, "");
ZipEntry entry = new ZipEntry(writeFilePath);
entry.DateTime = DateTime.Now;
entry.Size = fs.Length;
s.PutNextEntry(entry);
// 1G
long blockSize = 51200;
var size = (int)fs.Length;
var oneG = 1024 * 1024 * 1024;
if (size > oneG)
{
blockSize = oneG;
}
byte[] buffer = new byte[blockSize];
size = fs.Read(buffer, 0, buffer.Length);
s.Write(buffer, 0, size);
while (size < fs.Length)
{
int sizeRead = fs.Read(buffer, 0, buffer.Length);
s.Write(buffer, 0, sizeRead);
size += sizeRead;
}
s.Flush(); // ,
fs.Close();
}
}
}
}
유일 하 게 주의해 야 할 점 은 압축 을 풀 수 있 는 디 렉 터 리 구조 와 압축 전의 파일 디 렉 터 리 가 다 를 수 있 습 니 다.이 때 parentPath 인 자 를 검사 합 니 다.ZipEntry 실체 new 를 사용 할 때 절대 경 로 를 현재 의 상대 경로 로 바 꿉 니 다.즉,상대 적 으로 압축 된 폴 더 의 경로 입 니 다.위의 방법 은 비교적 복잡 하고 상대 적 으로 간단 한 방식 도 있 습 니 다.api 를 직접 호출 합 니 다.
public static string ZipFolder(string sourceFolder, string zipFile)
{
string result = "";
try
{
//
if (!Directory.Exists(sourceFolder)) return result = " ";
DirectoryInfo d = new DirectoryInfo(sourceFolder);
var files = d.GetFiles();
if (files.Length == 0)
{
//
var ds = d.GetDirectories();
if (ds.Length > 0)
{
files = ds[0].GetFiles();
}
}
if (files.Length == 0) return result = " ";
System.IO.Compression.ZipFile.CreateFromDirectory(sourceFolder, zipFile);
}
catch (Exception ex)
{
result += " :" + ex.Message;
}
return result;
}
이상 은 어떻게 C\#로 압축 파일 을 실현 하 는 지 에 대한 상세 한 내용 입 니 다.C\#압축 파일 에 관 한 자 료 는 다른 관련 글 에 주목 하 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
WebView2를 Visual Studio 2017 Express에서 사용할 수 있을 때까지Evergreen .Net Framework SDK 4.8 VisualStudio2017에서 NuGet을 사용하기 때문에 패키지 관리 방법을 packages.config 대신 PackageReference를 사용해야...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.