/// <summary> /// Copy the contents of a stored file into an opened stream /// </summary> /// <param name="_zfe">Entry information of file to extract</param> /// <param name="_stream">Stream to store the uncompressed data</param> /// <returns>True if success, false if not.</returns> /// <remarks>Unique compression methods are Store and Deflate</remarks> public bool ExtractFile(ZipFileEntry _zfe, Stream _stream) { if (!_stream.CanWrite) throw new InvalidOperationException("Stream cannot be written"); // check signature byte[] signature = new byte[4]; this.ZipFileStream.Seek(_zfe.HeaderOffset, SeekOrigin.Begin); this.ZipFileStream.Read(signature, 0, 4); if (BitConverter.ToUInt32(signature, 0) != 0x04034b50) return false; // Select input stream for inflating or just reading Stream inStream; if (_zfe.Method == Compression.Store) inStream = this.ZipFileStream; else if (_zfe.Method == Compression.Deflate) inStream = new DeflateStream(this.ZipFileStream, CompressionMode.Decompress, true); else return false; // Buffered copy byte[] buffer = new byte[16384]; this.ZipFileStream.Seek(_zfe.FileOffset, SeekOrigin.Begin); uint bytesPending = _zfe.FileSize; while (bytesPending > 0) { int bytesRead = inStream.Read(buffer, 0, (int)Math.Min(bytesPending, buffer.Length)); _stream.Write(buffer, 0, bytesRead); bytesPending -= (uint)bytesRead; } _stream.Flush(); if (_zfe.Method == Compression.Deflate) inStream.Dispose(); return true; }
// 获得资源。写入文件的版本。特别适用于获得资源,也可用于获得主记录体。 // parameters: // fileTarget 文件。注意在调用函数前适当设置文件指针位置。函数只会在当前位置开始向后写,写入前不会主动改变文件指针。 // strStyleParam 一般设置为"content,data,metadata,timestamp,outputpath"; // input_timestamp 若!=null,则本函数会把第一个返回的timestamp和本参数内容比较,如果不相等,则报错 // return: // -1 出错。具体出错原因在this.ErrorCode中。this.ErrorInfo中有出错信息。 // 0 成功 public long GetRes(string strPath, Stream fileTarget, FlushOutput flushOutputMethod, DigitalPlatform.Stop stop, string strStyleParam, byte[] input_timestamp, out string strMetaData, out byte[] baOutputTimeStamp, out string strOutputPath, out string strError) { strError = ""; baOutputTimeStamp = null; strMetaData = ""; strOutputPath = ""; this.ErrorCode = ChannelErrorCode.None; this.ErrorInfo = ""; string strStyle = strStyleParam; if (StringUtil.IsInList("attachment", strStyle) == true) { Debug.Assert(false, "attachment style暂时不能使用"); } // 检查参数 if (StringUtil.IsInList("data", strStyle) == false) { if (fileTarget != null) { strError = "strStyle参数中若不包含data风格,则无法获得数据..."; return -1; } } if (StringUtil.IsInList("data", strStyle) == true) { if (fileTarget == null) { strError = "strStyle参数中若包含data风格,而fileTarget为null,会浪费通讯资源..."; return -1; } } bool bHasMetadataStyle = false; if (StringUtil.IsInList("metadata", strStyle) == true) { bHasMetadataStyle = true; } // string id = ""; byte[] baContent = null; long lStart = 0; int nPerLength = -1; byte[] old_timestamp = null; byte[] timestamp = null; long lTotalLength = -1; for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 if (stop != null && stop.State != 0) { strError = "用户中断"; return -1; } REDO: try { string strMessage = ""; string strPercent = ""; if (lTotalLength != -1) { double ratio = (double)lStart / (double)lTotalLength; strPercent = String.Format("{0,3:N}", ratio * (double)100) + "%"; } if (stop != null) { strMessage = "正在下载 " + Convert.ToString(lStart) + "-" + (lTotalLength == -1 ? "?" : Convert.ToString(lTotalLength)) + " " + strPercent + " " + strPath; stop.SetMessage(strMessage); } IAsyncResult soapresult = this.ws.BeginGetRes(strPath, fileTarget == null ? 0 : lStart, fileTarget == null ? 0 : nPerLength, strStyle, null, null); for (; ; ) { /* try { Application.DoEvents(); // 出让界面控制权 } catch { } // System.Threading.Thread.Sleep(10); // 避免CPU资源过度耗费 */ DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } // string strOutputResPath; Result result = this.ws.EndGetRes( out baContent, // out id, out strMetaData, out strOutputPath, out timestamp, soapresult); // 即便不是返回-1,也可能有错误码和错误信息字符串 ConvertErrorCode(result); strError = result.ErrorString; if (result.Value == -1) { if (result.ErrorCode == ErrorCodeValue.NotLogin && this.Container != null) { // return: // -1 error // 0 login failed // 1 login succeed int nRet = this.UiLogin(strPath, out strError); if (nRet == -1 || nRet == 0) { return -1; } goto REDO; } /* ConvertErrorCode(result); strError = result.ErrorString; */ return -1; } if (bHasMetadataStyle == true) { StringUtil.RemoveFromInList("metadata", true, ref strStyle); bHasMetadataStyle = false; } lTotalLength = result.Value; if (StringUtil.IsInList("timestamp", strStyle) == true /* && lTotalLength > 0 * */ ) // 2012/1/11 { if (input_timestamp != null) { if (ByteArray.Compare(input_timestamp, timestamp) != 0) { strError = "下载过程中发现时间戳和input_timestamp参数中的时间戳不一致,下载失败 ..."; return -1; } } if (old_timestamp != null) { if (ByteArray.Compare(old_timestamp, timestamp) != 0) { strError = "下载过程中发现时间戳变化,下载失败 ..."; return -1; } } } old_timestamp = timestamp; if (fileTarget == null) break; // 写入文件 if (StringUtil.IsInList("attachment", strStyle) == true) { Debug.Assert(false, "attachment style暂时不能使用"); /* Attachment attachment = ws.ResponseSoapContext.Attachments[id]; if (attachment == null) { strError = "id为 '" +id+ "' 的attachment在WebService响应中没有找到..."; return -1; } StreamUtil.DumpStream(attachment.Stream, fileTarget); nStart += (int)attachment.Stream.Length; Debug.Assert(attachment.Stream.Length <= result.Value, "每次返回的包尺寸["+Convert.ToString(attachment.Stream.Length)+"]应当小于result.Value["+Convert.ToString(result.Value)+"]"); */ } else { Debug.Assert(StringUtil.IsInList("content", strStyle) == true, "不是attachment风格,就应是content风格"); Debug.Assert(baContent != null, "返回的baContent不能为null"); Debug.Assert(baContent.Length <= result.Value, "每次返回的包尺寸[" + Convert.ToString(baContent.Length) + "]应当小于result.Value[" + Convert.ToString(result.Value) + "]"); fileTarget.Write(baContent, 0, baContent.Length); if (flushOutputMethod != null) { if (flushOutputMethod() == false) { strError = "FlushOutputMethod()用户中断"; return -1; } } lStart += baContent.Length; } if (lStart >= result.Value) break; // 结束 } // end try catch (Exception ex) { /* strError = ConvertWebError(ex); return -1; * */ int nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; goto REDO; } } // end of for baOutputTimeStamp = timestamp; this.ClearRedoCount(); return 0; }
public static void WriteString(Stream s, string v) { MemoryStream baos = new MemoryStream(); for (int index = 0; index < v.Length; index++) { #if CODE_ANALYSIS char c = v.CharAt(index); #else char c = v[index]; #endif if ((c > 0) && (c < 80)) baos.WriteByte((byte)c); else if (c < '\u0800') { baos.WriteByte((byte)(0xc0 | (0x1f & (c >> 6)))); baos.WriteByte((byte)(0x80 | (0x3f & c))); } else { baos.WriteByte((byte)(0xe0 | (0x0f & (c >> 12)))); baos.WriteByte((byte)(0x80 | (0x3f & (c >> 6)))); baos.WriteByte((byte)(0x80 | (0x3f & c))); } } WriteUInt16(s, (ushort)baos.Length); s.Write(baos.GetBuffer(), 0, (int)baos.Length); }
/// <summary> /// Convenience method which writes the contents of the ZipEntry /// to the specified stream and returns the number of bytes written. /// </summary> /// <param name="stream">The stream.</param> /// <returns></returns> public int WriteTo(Stream stream) { byte[] buffer = new byte[GlobalConstants.DefaultStreamBlockSize]; int bytesRead, totalBytesRead = 0; while ((bytesRead = Read(buffer, 0, GlobalConstants.DefaultStreamBlockSize)) > -1) { stream.Write(buffer, 0, bytesRead); totalBytesRead += bytesRead; } return totalBytesRead; }