C#实现多级子目录Zip压缩解压实例

时间:2023-03-08 19:30:06
C#实现多级子目录Zip压缩解压实例

   
 

参考

https://blog.csdn.net/lki_suidongdong/article/details/20942977

重点:

实现多级子目录的压缩,类似winrar,可以选择是否排除基准目录

   
 

C#实现多级子目录Zip压缩解压实例

   
 

   
 

   
 

C#实现多级子目录Zip压缩解压实例

   
 

 
 

 
 

 
 

 1
public
void ZipDirectoryTest()

 2
{

 3
string path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), DateTime.Now.Ticks.ToString());

 4
foreach (string sub in
new
string[] { "bin", "release", "test", "test\\bin", "" })

 5
{

 6
string subPath = System.IO.Path.Combine(path, sub);

 7
if (!System.IO.Directory.Exists(subPath))

 8
System.IO.Directory.CreateDirectory(subPath);

 9 System.IO.File.WriteAllText(System.IO.Path.Combine(subPath, "1.cs"), "");

10 System.IO.File.WriteAllText(System.IO.Path.Combine(subPath, "1.txt"), "");

11 System.IO.File.WriteAllText(System.IO.Path.Combine(subPath, "1.html"), "");

12 System.IO.File.WriteAllText(System.IO.Path.Combine(subPath, "1.bin"), "");

13

14
}

15
Console.WriteLine(path);

16

17
new ZipHelper().ZipDirectory(path, "e:\\temp\\tt.zip",false);

18 ZipHelper.UnZip("e:\\temp\\tt.zip", "e:\\temp\\tt2");

19
//System.IO.Directory.Delete(path, true);

20
//Q.Helper.FileHelper.SelectFile(path);

21 }

 
 

代码

  
 

  1
using System;

  2

  3
using System.Collections.Generic;

  4

  5
using System.Linq;

  6

  7
using System.Text;

  8

  9
using System.IO;

 10

 11
using ICSharpCode.SharpZipLib;

 12

 13
using ICSharpCode.SharpZipLib.Zip;

 14

 15
#if NETSTANDARD2_0

 16

 17
using ICSharpCode.SharpZipLib.Checksum;

 18

 19
#else

 20

 21
using ICSharpCode.SharpZipLib.Checksums;

 22

 23
#endif

 24

 25

 26

 27
namespace Q.Helper.Zip

 28

 29
{

 30

 31

 32

 33
///
<summary>

 34

 35
/// 适用与ZIP压缩

 36

 37
///
</summary>

 38

 39
public
class ZipHelper

 40

 41
{

 42

 43
public
int Level

 44

 45
{

 46

 47
get; set;

 48

 49
}

 50

 51
#region 压缩

 52

 53

 54

 55
///
<summary>

 56

 57
/// 递归压缩文件夹的内部方法(排除相对路径)

 58

 59
///
</summary>

 60

 61
///
<param name="folderToZip">要压缩的文件夹路径</param>

 62

 63
///
<param name="zipStream">压缩输出流</param>

 64

 65
///
<param name="parentFolderName">此文件夹的上级文件夹</param>

 66

 67
///
<param name="includeFloderName">是否包含目录名</param>

 68

 69
///
<returns></returns>

 70

 71
private
bool ZipDirectory(string folderToZip, ZipOutputStream zipStream, string parentFolderName, bool createBaseFolder = true)

 72

 73
{

 74

 75 folderToZip = folderToZip.Replace("\\", "/");

 76

 77
bool result = true;

 78

 79
string[] folders, files;

 80

 81 ZipEntry ent = null;

 82

 83 FileStream fs = null;

 84

 85 Crc32 crc = new Crc32();

 86

 87

 88

 89
try

 90

 91
{

 92

 93
string entPath = Path.Combine(parentFolderName, Path.GetFileName(folderToZip) + "/").Replace("\\", "/");

 94

 95
if (!createBaseFolder)

 96

 97 entPath = entPath.Substring(entPath.IndexOf("/") + 1);

 98

 99
if (!string.IsNullOrEmpty(entPath))

100

101
{

102

103 ent = new ZipEntry(entPath);

104

105
Console.WriteLine(entPath);

106

107
zipStream.PutNextEntry(ent);

108

109
zipStream.Flush();

110

111
}

112

113 files = Directory.GetFiles(folderToZip);

114

115
foreach (string file in files)

116

117
{

118

119 fs = File.OpenRead(file);

120

121

122

123
byte[] buffer = new
byte[fs.Length];

124

125 fs.Read(buffer, 0, buffer.Length);

126

127 entPath = Path.Combine(parentFolderName, Path.GetFileName(folderToZip) + "/" + Path.GetFileName(file)).Replace("\\", "/");

128

129
if (!createBaseFolder)

130

131 entPath = entPath.Substring(entPath.IndexOf("/") + 1);

132

133
Console.WriteLine(entPath);

134

135 ent = new ZipEntry(entPath);

136

137 ent.DateTime = DateTime.Now;

138

139 ent.Size = fs.Length;

140

141

142

143
fs.Close();

144

145

146

147
crc.Reset();

148

149
crc.Update(buffer);

150

151

152

153 ent.Crc = crc.Value;

154

155
zipStream.PutNextEntry(ent);

156

157 zipStream.Write(buffer, 0, buffer.Length);

158

159
}

160

161

162

163
}

164

165
catch (Exception ex)

166

167
{

168

169 result = false;

170

171
throw ex;

172

173
}

174

175
finally

176

177
{

178

179
if (fs != null)

180

181
{

182

183
fs.Close();

184

185
fs.Dispose();

186

187
}

188

189
if (ent != null)

190

191
{

192

193 ent = null;

194

195
}

196

197
GC.Collect();

198

199 GC.Collect(1);

200

201
}

202

203

204

205 folders = Directory.GetDirectories(folderToZip);

206

207
//多级递归时需要记住相对目录

208

209
foreach (string folder in folders)

210

211
{

212

213
if (!ZipDirectory(folder, zipStream, Path.Combine(parentFolderName, Path.GetFileName(folderToZip)), createBaseFolder))

214

215
return
false;

216

217
}

218

219
return result;

220

221
}

222

223

224

225
///
<summary>

226

227
/// 压缩文件夹

228

229
///
</summary>

230

231
///
<param name="folderToZip">要压缩的文件夹路径</param>

232

233
///
<param name="zipedFile">压缩文件完整路径</param>

234

235
///
<param name="password">密码</param>

236

237
///
<returns>是否压缩成功</returns>

238

239
public
bool ZipDirectory(string folderToZip, string zipedFile, string password, bool includeFloderName = true)

240

241
{

242

243
bool result = false;

244

245
if (!Directory.Exists(folderToZip))

246

247
return result;

248

249

250

251 ZipOutputStream zipStream = new ZipOutputStream(File.Create(zipedFile));

252

253
zipStream.SetLevel(Level);

254

255
if (!string.IsNullOrEmpty(password)) zipStream.Password = password;

256

257

258

259 result = ZipDirectory(folderToZip, zipStream, "", includeFloderName);

260

261

262

263
zipStream.Finish();

264

265
zipStream.Close();

266

267

268

269
return result;

270

271
}

272

273

274

275
///
<summary>

276

277
/// 压缩文件夹

278

279
///
</summary>

280

281
///
<param name="folderToZip">要压缩的文件夹路径</param>

282

283
///
<param name="zipedFile">压缩文件完整路径</param>

284

285
///
<returns>是否压缩成功</returns>

286

287
public
bool ZipDirectory(string folderToZip, string zipedFile, bool includeFloderName = true)

288

289
{

290

291
bool result = ZipDirectory(folderToZip, zipedFile, "", includeFloderName);

292

293
return result;

294

295
}

296

297

298

299
///
<summary>

300

301
/// 压缩文件

302

303
///
</summary>

304

305
///
<param name="fileToZip">要压缩的文件全名</param>

306

307
///
<param name="zipedFile">压缩后的文件名</param>

308

309
///
<param name="password">密码</param>

310

311
///
<returns>压缩结果</returns>

312

313
public
bool ZipFile(string fileToZip, string zipedFile, string password)

314

315
{

316

317
bool result = true;

318

319 ZipOutputStream zipStream = null;

320

321 FileStream fs = null;

322

323 ZipEntry ent = null;

324

325

326

327
if (!File.Exists(fileToZip))

328

329
return
false;

330

331

332

333
try

334

335
{

336

337 fs = File.OpenRead(fileToZip);

338

339
byte[] buffer = new
byte[fs.Length];

340

341 fs.Read(buffer, 0, buffer.Length);

342

343
fs.Close();

344

345

346

347 fs = File.Create(zipedFile);

348

349 zipStream = new ZipOutputStream(fs);

350

351
if (!string.IsNullOrEmpty(password)) zipStream.Password = password;

352

353 ent = new ZipEntry(Path.GetFileName(fileToZip));

354

355
zipStream.PutNextEntry(ent);

356

357
zipStream.SetLevel(Level);

358

359

360

361 zipStream.Write(buffer, 0, buffer.Length);

362

363

364

365
}

366

367
catch

368

369
{

370

371 result = false;

372

373
}

374

375
finally

376

377
{

378

379
if (zipStream != null)

380

381
{

382

383
zipStream.Finish();

384

385
zipStream.Close();

386

387
}

388

389
if (ent != null)

390

391
{

392

393 ent = null;

394

395
}

396

397
if (fs != null)

398

399
{

400

401
fs.Close();

402

403
fs.Dispose();

404

405
}

406

407
}

408

409
GC.Collect();

410

411 GC.Collect(1);

412

413

414

415
return result;

416

417
}

418

419

420

421
///
<summary>

422

423
/// 压缩文件

424

425
///
</summary>

426

427
///
<param name="fileToZip">要压缩的文件全名</param>

428

429
///
<param name="zipedFile">压缩后的文件名</param>

430

431
///
<returns>压缩结果</returns>

432

433
public
bool ZipFile(string fileToZip, string zipedFile)

434

435
{

436

437
bool result = ZipFile(fileToZip, zipedFile, null);

438

439
return result;

440

441
}

442

443

444

445
///
<summary>

446

447
/// 压缩文件或文件夹

448

449
///
</summary>

450

451
///
<param name="fileToZip">要压缩的路径</param>

452

453
///
<param name="zipedFile">压缩后的文件名</param>

454

455
///
<param name="password">密码</param>

456

457
///
<returns>压缩结果</returns>

458

459
public
bool Zip(string fileToZip, string zipedFile, string password)

460

461
{

462

463
bool result = false;

464

465
if (Directory.Exists(fileToZip))

466

467 result = ZipDirectory(fileToZip, zipedFile, password);

468

469
else
if (File.Exists(fileToZip))

470

471 result = ZipFile(fileToZip, zipedFile, password);

472

473

474

475
return result;

476

477
}

478

479

480

481
///
<summary>

482

483
/// 压缩文件或文件夹

484

485
///
</summary>

486

487
///
<param name="fileToZip">要压缩的路径</param>

488

489
///
<param name="zipedFile">压缩后的文件名</param>

490

491
///
<returns>压缩结果</returns>

492

493
public
bool Zip(string fileToZip, string zipedFile)

494

495
{

496

497
bool result = Zip(fileToZip, zipedFile, null);

498

499
return result;

500

501

502

503
}

504

505

506

507
#endregion

508

509

510

511
#region 解压

512

513

514

515
///
<summary>

516

517
/// 解压功能(解压压缩文件到指定目录)

518

519
///
</summary>

520

521
///
<param name="fileToUnZip">待解压的文件</param>

522

523
///
<param name="zipedFolder">指定解压目标目录</param>

524

525
///
<param name="password">密码</param>

526

527
///
<returns>解压结果</returns>

528

529
public
static
bool UnZip(string fileToUnZip, string zipedFolder, string password)

530

531
{

532

533
bool result = true;

534

535

536

537 ZipInputStream zipStream = null;

538

539 ZipEntry ent = null;

540

541
string fileName;

542

543

544

545
if (!File.Exists(fileToUnZip))

546

547
return
false;

548

549

550

551
if (!Directory.Exists(zipedFolder))

552

553
Directory.CreateDirectory(zipedFolder);

554

555

556

557
try

558

559
{

560

561 zipStream = new ZipInputStream(File.OpenRead(fileToUnZip));

562

563
if (!string.IsNullOrEmpty(password)) zipStream.Password = password;

564

565
while ((ent = zipStream.GetNextEntry()) != null)

566

567
{

568

569
if (!string.IsNullOrEmpty(ent.Name))

570

571
{

572

573 fileName = Path.Combine(zipedFolder, ent.Name);

574

575 fileName = fileName.Replace('/', '\\');//change by Mr.HopeGi

576

577

578

579
if (fileName.EndsWith("\\"))

580

581
{

582

583
Directory.CreateDirectory(fileName);

584

585
continue;

586

587
}

588

589
using (FileStream fs = File.Create(fileName))

590

591
{

592

593
int size = 2048;

594

595
byte[] data = new
byte[size];

596

597
while (true)

598

599
{

600

601

602

603 size = zipStream.Read(data, 0, data.Length);

604

605
if (size > 0)

606

607 fs.Write(data, 0, data.Length);

608

609
else

610

611
break;

612

613
}

614

615
fs.Flush();

616

617

618

619
fs.Close();

620

621
new FileInfo(fileName).LastWriteTime = ent.DateTime;

622

623
}

624

625

626

627
}

628

629
}

630

631
}

632

633
catch

634

635
{

636

637 result = false;

638

639
}

640

641
finally

642

643
{

644

645

646

647
if (zipStream != null)

648

649
{

650

651
zipStream.Close();

652

653
zipStream.Dispose();

654

655
}

656

657
if (ent != null)

658

659
{

660

661 ent = null;

662

663
}

664

665
GC.Collect();

666

667 GC.Collect(1);

668

669
}

670

671
return result;

672

673
}

674

675

676

677
///
<summary>

678

679
/// 解压功能(解压压缩文件到指定目录)

680

681
///
</summary>

682

683
///
<param name="fileToUnZip">待解压的文件</param>

684

685
///
<param name="zipedFolder">指定解压目标目录</param>

686

687
///
<returns>解压结果</returns>

688

689
public
static
bool UnZip(string fileToUnZip, string zipedFolder)

690

691
{

692

693
bool result = UnZip(fileToUnZip, zipedFolder, null);

694

695
return result;

696

697
}

698

699

700

701
#endregion

702

703
}

704

705 }