您目前尚未登陆,请选择【登陆】或【注册
首页->博客论坛->X3BLOG 单用户1.0 build80707(ACCESS)源代码>>SharpZipLib/Zip/ZipOutputStream.cs>>代码在线查看
温馨提示:代码在线浏览功能只能做为源码浏览参考,不能展示项目的全部,如果想更进一步了解该代码请下载: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 40using System; 41using System.IO; 42using System.Collections; 43using System.Text; 44 45using ICSharpCode.SharpZipLib.Checksums; 46using ICSharpCode.SharpZipLib.Zip.Compression; 47using ICSharpCode.SharpZipLib.Zip.Compression.Streams; 48 49namespace 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