温馨提示:代码在线浏览功能只能做为源码浏览参考,不能展示项目的全部,如果想更进一步了解该代码请下载:X3BLOG 单用户1.0 build80707(ACCESS)源代码
当前文件路径:x3blogAccessBuild80707/SharpZipLib/Zip/ZipOutputStream.cs

1// ZipOutputStream.cs 2
// 3
// Copyright (C) 2001 Mike Krueger 4
// Copyright (C) 2004 John Reilly 5
// 6
// This file was translated from java, it was part of the GNU Classpath 7
// Copyright (C) 2001 Free Software Foundation, Inc. 8
// 9
// This program is free software; you can redistribute it and/or 10
// modify it under the terms of the GNU General Public License 11
// as published by the Free Software Foundation; either version 2 12
// of the License, or (at your option) any later version. 13
// 14
// This program is distributed in the hope that it will be useful, 15
// but WITHOUT ANY WARRANTY; without even the implied warranty of 16
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17
// GNU General Public License for more details. 18
// 19
// You should have received a copy of the GNU General Public License 20
// along with this program; if not, write to the Free Software 21
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22
// 23
// Linking this library statically or dynamically with other modules is 24
// making a combined work based on this library. Thus, the terms and 25
// conditions of the GNU General Public License cover the whole 26
// combination. 27
// 28
// As a special exception, the copyright holders of this library give you 29
// permission to link this library with independent modules to produce an 30
// executable, regardless of the license terms of these independent 31
// modules, and to copy and distribute the resulting executable under 32
// terms of your choice, provided that you also meet, for each linked 33
// independent module, the terms and conditions of the license of that 34
// module. An independent module is a module which is not derived from 35
// or based on this library. If you modify this library, you may extend 36
// this exception to your version of the library, but you are not 37
// obligated to do so. If you do not wish to do so, delete this 38
// exception statement from your version. 39
40
using System; 41
using System.IO; 42
using System.Collections; 43
using System.Text; 44
45
using ICSharpCode.SharpZipLib.Checksums; 46
using ICSharpCode.SharpZipLib.Zip.Compression; 47
using ICSharpCode.SharpZipLib.Zip.Compression.Streams; 48
49
namespace ICSharpCode.SharpZipLib.Zip 50
{ 51
/// <summary> 52
/// This is a DeflaterOutputStream that writes the files into a zip 53
/// archive one after another. It has a special method to start a new 54
/// zip entry. The zip entries contains information about the file name 55
/// size, compressed size, CRC, etc. 56
/// 57
/// It includes support for Stored and Deflated entries. 58
/// This class is not thread safe. 59
/// <br/> 60
/// <br/>Author of the original java version : Jochen Hoenicke 61
/// </summary> 62
/// <example> This sample shows how to create a zip file 63
/// <code> 64
/// using System; 65
/// using System.IO; 66
/// 67
/// using ICSharpCode.SharpZipLib.Zip; 68
/// 69
/// class MainClass 70
/// { 71
/// public static void Main(string[] args) 72
/// { 73
/// string[] filenames = Directory.GetFiles(args[0]); 74
/// 75
/// ZipOutputStream s = new ZipOutputStream(File.Create(args[1])); 76
/// 77
/// s.SetLevel(5); // 0 - store only to 9 - means best compression 78
/// 79
/// foreach (string file in filenames) { 80
/// FileStream fs = File.OpenRead(file); 81
/// 82
/// byte[] buffer = new byte[fs.Length]; 83
/// fs.Read(buffer, 0, buffer.Length); 84
/// 85
/// ZipEntry entry = new ZipEntry(file); 86
/// 87
/// s.PutNextEntry(entry); 88
/// 89
/// s.Write(buffer, 0, buffer.Length); 90
/// 91
/// } 92
/// 93
/// s.Finish(); 94
/// s.Close(); 95
/// } 96
/// } 97
/// </code> 98
/// </example> 99
public class ZipOutputStream : DeflaterOutputStream 100
{ 101
private ArrayList entries = new ArrayList(); 102
private Crc32 crc = new Crc32(); 103
private ZipEntry curEntry = null; 104
105
int defaultCompressionLevel = Deflater.DEFAULT_COMPRESSION; 106
CompressionMethod curMethod = CompressionMethod.Deflated; 107
108
109
private long size; 110
private long offset = 0; 111
112
private byte[] zipComment = new byte[0]; 113
114
/// <summary> 115
/// Gets boolean indicating central header has been added for this archive... 116
/// No further entries can be added once this has been done. 117
/// </summary> 118
public bool IsFinished { 119
get { 120
return entries == null; 121
} 122
} 123
124
/// <summary> 125
/// Creates a new Zip output stream, writing a zip archive. 126
/// </summary> 127
/// <param name="baseOutputStream"> 128
/// The output stream to which the archive contents are written. 129
/// </param> 130
public ZipOutputStream(Stream baseOutputStream) : base(baseOutputStream, new Deflater(Deflater.DEFAULT_COMPRESSION, true)) 131
{ 132
} 133
134
/// <summary> 135
/// Set the zip file comment. 136
/// </summary> 137
/// <param name="comment"> 138
/// The comment string 139
/// </param> 140
/// <exception name ="ArgumentOutOfRangeException"> 141
/// Encoding of comment is longer than 0xffff bytes. 142
/// </exception> 143
public void SetComment(string comment) 144
{ 145
byte[] commentBytes = ZipConstants.ConvertToArray(comment); 146
if (commentBytes.Length > 0xffff) { 147
throw new ArgumentOutOfRangeException("comment"); 148
} 149
zipComment = commentBytes; 150
} 151
152
/// <summary> 153
/// Sets default compression level. The new level will be activated 154
/// immediately. 155
/// </summary> 156
/// <exception cref="ArgumentOutOfRangeException"> 157
/// Level specified is not supported. 158
/// </exception> 159
/// <see cref="Deflater"/> 160
public void SetLevel(int level) 161
{ 162
defaultCompressionLevel = level; 163
def.SetLevel(level); 164
} 165
166
/// <summary> 167
/// Get the current deflate compression level 168
/// </summary> 169
/// <returns>The current compression level</returns> 170
public int GetLevel() 171
{ 172
return def.GetLevel(); 173
} 174
175
/// <summary> 176
/// Write an unsigned short in little endian byte order. 177
/// </summary> 178
private void WriteLeShort(int value) 179
{ 180
baseOutputStream.WriteByte((byte)(value & 0xff)); 181
baseOutputStream.WriteByte((byte)((value >> 8) & 0xff)); 182
} 183
184
/// <summary> 185
/// Write an int in little endian byte order. 186
/// </summary> 187
private void WriteLeInt(int value) 188
{ 189
WriteLeShort(value); 190
WriteLeShort(value >> 16); 191
} 192
193
/// <summary> 194
/// Write an int in little endian byte order. 195
/// </summary> 196
private void WriteLeLong(long value) 197
{ 198
WriteLeInt((int)value); 199
WriteLeInt((int)(value >> 32)); 200
} 201
202
203
bool patchEntryHeader = false; 204
205
long headerPatchPos = -1; 206
207
/// <summary> 208
/// Starts a new Zip entry. It automatically closes the previous 209
/// entry if present. 210
/// All entry elements bar name are optional, but must be correct if present. 211
/// If the compression method is stored and the output is not patchable 212
/// the compression for that entry is automatically changed to deflate level 0 213
/// </summary> 214
/// <param name="entry"> 215
/// the entry. 216
/// </param> 217
/// <exception cref="System.IO.IOException"> 218
/// if an I/O error occured. 219
/// </exception> 220
/// <exception cref="System.InvalidOperationException"> 221
/// if stream was finished 222
/// </exception> 223
/// <exception cref="ZipException"> 224
/// Too many entries in the Zip file<br/> 225
/// Entry name is too long<br/> 226
/// Finish has already been called<br/> 227
/// </exception> 228
public void PutNextEntry(ZipEntry entry) 229
{ 230
if (entries == null) { 231
throw new InvalidOperationException("ZipOutputStream was finished"); 232
} 233
234
if (curEntry != null) { 235
CloseEntry(); 236
} 237
238
if (entries.Count >= 0xffff) { 239
throw new ZipException("Too many entries for Zip file"); 240
} 241
242
CompressionMethod method = entry.CompressionMethod; 243
int compressionLevel = defaultCompressionLevel; 244
245
entry.Flags = 0; 246
patchEntryHeader = false; 247
bool headerInfoAvailable = true; 248
249
if (method == CompressionMethod.Stored) { 250
if (entry.CompressedSize >= 0) { 251
if (entry.Size < 0) { 252
entry.Size = entry.CompressedSize; 253
} else if (entry.Size != entry.CompressedSize) { 254
throw new ZipException("Method STORED, but compressed size != size"); 255
} 256
} else { 257
if (entry.Size >= 0) { 258
entry.CompressedSize = entry.Size; 259
} 260
} 261
262
if (entry.Size < 0 || entry.Crc < 0) { 263
if (CanPatchEntries == true) { 264
headerInfoAvailable = false; 265
} 266
else { 267
// Cant patch entries so storing is not possible. 268
method = CompressionMethod.Deflated; 269
compressionLevel = 0; 270
} 271
} 272
} 273
274
if (method == CompressionMethod.Deflated) { 275
if (entry.Size == 0) { 276
// No need to compress - no data. 277
entry.CompressedSize = entry.Size; 278
entry.Crc = 0; 279
method = CompressionMethod.Stored; 280
} else if (entry.CompressedSize < 0 || entry.Size < 0 || entry.Crc < 0) { 281
headerInfoAvailable = false; 282
} 283
} 284
285
if (headerInfoAvailable == false) { 286
if (CanPatchEntries == false) { 287
entry.Flags |= 8; 288
} else { 289
patchEntryHeader = true; 290
} 291
} 292
293
if (Password != null) { 294
entry.IsCrypted = true; 295
if (entry.Crc < 0) { 296
// Need to append data descriptor as crc is used for encryption and its not known. 297
entry.Flags |= 8; 298
} 299
} 300




