银河

SKYIV STUDIO

  博客园 :: 首页 ::  ::  :: 订阅 订阅 :: 管理 ::
  105 随笔 :: 2 文章 :: 753 评论 :: 22 引用

我最近要写一个供有相关权限的管理人员查询大额资金明细的程序,界面如下:


所需的数据文件是放在报表服务器上,每天一个压缩文件,该压缩文件中除了所需的储蓄流水账文件外,还有很多其他的文件。如果先把该压缩文件从报表服务器下载到应用服务器上,再进行解压缩处理的话,一是多下载了该压缩文件中我们不需要的其他文件,二是还必须在应用服务器上建立以SessionID等方法标识的临时文件,以免其他用户也在进行查询时文件名冲突,三是使用完毕后还必须删除该临时文件。
我的处理方法是如下:
using (ZipInputStream zs = Zip.GetZipInputStream((new FtpClient(Pub.Ftp1Uri, Pub.Ftp1User, Pub.Ftp1Pswd)).
        GetDownloadStream(Path.Combine(Pub.Ftp1EPath, zipFileName)), binFileName, out size))
      {
        if (size % Pub.P_R2 != 0) throw new ApplicationException("文件长度错: " + binFileName);
        byte [] bs = new byte[Pub.P_R2];
        long recs = size / Pub.P_R2;
        for (long rec = 0; rec < recs; rec++)
        {
          Zip.ReadStream(zs, bs);
          ...
      }
首先,用 FtpClient.GetDownloadStream() 方法得到一个对应于FTP服务器上文件的Stream,然后把这个Stream传给Zip.GetZipInputStream()方法,得到一个ZipInputStream,然后使用Zip.ReadStream()方法一行一行读取储蓄流水账文件到byte[]中去,这样就取得了我们所需的数据,就象储蓄流水账文件就存放在本地硬盘上一样,避免了下载文件和解压文件。具体代码如下:

 1using System;
 2using System.IO;
 3using System.Net;
 4
 5namespace Skyiv.Util
 6{
 7  sealed class FtpClient
 8  {
 9    Uri uri;
10    string userName;
11    string password;
12    
13    public FtpClient(string uri, string userName, string password)
14    {
15      this.uri = new Uri(uri);
16      this.userName = userName;
17      this.password = password;
18    }

19    
20    public Stream GetDownloadStream(string sourceFile)
21    {
22      Uri downloadUri = new Uri(uri, sourceFile);
23      if (downloadUri.Scheme != Uri.UriSchemeFtp) throw new ArgumentException("URI is not an FTP site");
24      FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(downloadUri);
25      ftpRequest.Credentials = new NetworkCredential(userName, password);
26      ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
27      return ((FtpWebResponse)ftpRequest.GetResponse()).GetResponseStream();
28    }

29    
30    /*public */void Download(string sourceFile, string destinationFile)
31    {
32      using (Stream reader = GetDownloadStream(sourceFile))
33      {
34        using (BinaryWriter bw = new BinaryWriter(new FileStream(destinationFile, FileMode.Create)))
35        {
36          for (;;)
37          {
38            int c = reader.ReadByte();
39            if (c == -1break;
40            bw.Write((byte)c);
41          }

42        }

43      }

44    }

45  }

46}

47
 1using System;
 2using System.IO;
 3using ICSharpCode.SharpZipLib.Zip;
 4
 5namespace Skyiv.Util
 6{
 7  static class Zip
 8  {
 9    public static void ReadStream(Stream inStream, byte [] bs)
10    {
11      int offset = 0;
12      int count = bs.Length;
13      do 
14      {
15        int size = inStream.Read(bs, offset, count);
16        if (size <= 0break;
17        offset += size;
18        count -= size;
19      }
 while (count > 0);
20      if (count != 0throw new ApplicationException("Zip.ReadStream(): 读输入流错");
21    }

22    
23    public static ZipInputStream GetZipInputStream(string zipFileName, string fileName, out long fileLength)
24    {
25      return GetZipInputStream(File.OpenRead(zipFileName), fileName, out fileLength);
26    }

27    
28    public static ZipInputStream GetZipInputStream(Stream zipStream, string fileName, out long fileLength)
29    {
30      ZipInputStream zs = new ZipInputStream(zipStream);
31      ZipEntry theEntry;
32      while ((theEntry = zs.GetNextEntry()) != null
33      {
34        if (Path.GetFileName(theEntry.Name) != fileName) continue;
35        fileLength = theEntry.Size;
36        return zs;
37      }

38      fileLength = -1;
39      return null;
40    }

41
42    /*public */static void UnzipFile(string zipFile, string baseStr, params string [] fileList)
43    {
44      UnzipFile(File.OpenRead(zipFile), baseStr, fileList);
45    }

46    
47    /*public */static void UnzipFile(Stream zipStream, string baseStr, params string [] fileList)
48    {
49      using (ZipInputStream zs = new ZipInputStream(zipStream))
50      {
51        ZipEntry theEntry;
52        byte[] data = new byte[4096];
53        while ((theEntry = zs.GetNextEntry()) != null{
54          if (Array.IndexOf(fileList, Path.GetFileName(theEntry.Name)) < 0continue;
55          using (FileStream sw = new FileStream(baseStr+Path.GetFileName(theEntry.Name), FileMode.Create))
56          {
57            while (true{
58              int size = zs.Read(data, 0, data.Length);
59              if (size <= 0break;
60              sw.Write(data, 0, size);
61            }

62          }

63        }

64      }

65    }

66  }

67}

68
 1    void MakeData(DateTime workDate, short brno, short currtype, decimal startAmt)
 2    {
 3      Pub.SetNOVA(workDate);
 4      string zipFileName = string.Format("e-{0:yyyyMMdd}-{1:D4}-0000{2}.zip", workDate, Pub.Zone, Pub.IsNOVAv12 ? "-2" : "");
 5      string binFileName = string.Format("e-{0:yyyyMMdd}-pfsjnl.bin", workDate);
 6      long size;
 7      DataTable dt = MakeDataTable();
 8      using (ZipInputStream zs = Zip.GetZipInputStream((new FtpClient(Pub.Ftp1Uri, Pub.Ftp1User, Pub.Ftp1Pswd)).
 9        GetDownloadStream(Path.Combine(Pub.Ftp1EPath, zipFileName)), binFileName, out size))
10      {
11        if (size % Pub.P_R2 != 0throw new ApplicationException("文件长度错: " + binFileName);
12        byte [] bs = new byte[Pub.P_R2];
13        long recs = size / Pub.P_R2;
14        for (long rec = 0; rec < recs; rec++)
15        {
16          Zip.ReadStream(zs, bs);
17          if (Etc.Encode.GetString(bs,Pub.P_R2_RevTran,Pub.L_Revtran) != "0"continue// 反交易标志
18          for (int i = 0; i < 2; i++)
19          {
20            bool isDebit = (i == 0);
21            if (int.Parse(Etc.Encode.GetString(bs,(isDebit?Pub.P_R2_Drcurr:Pub.P_R2_Crcurr),Pub.L_Curr)) != currtype) continue;
22            decimal amt0 = decimal.Parse(Etc.Encode.GetString(bs,(isDebit?Pub.P_R2_Amount1:Pub.P_R2_Amount2),Pub.L_Bal)) / 100;
23            if (Math.Abs(amt0) < startAmt) continue;
24            string account = Etc.Encode.GetString(bs,(isDebit?Pub.P_R2_Draccno:Pub.P_R2_Craccno),Pub.L_Accno);
25            if (!DbBranch.IsMyAccount(account, brno)) continue;
26            string customer = Etc.Encode.GetString(bs,Pub.P_R2_Notes1,Pub.L_Notes1).Trim('@'' ');
27            short nodeno = short.Parse(Etc.Encode.GetString(bs,Pub.P_R2_Brno,Pub.L_Brno));
28            int code = int.Parse(Etc.Encode.GetString(bs,Pub.P_R2_Trxcode,Pub.L_Trxcode));
29            DataRow dr = dt.NewRow();
30            dr["No"= nodeno;
31            dr["Name"= DbBranch.GetBrief(DbBranch.IsAllNode(brno), nodeno);
32            dr["Teller"= int.Parse(Etc.Encode.GetString(bs,Pub.P_R2_Teller,Pub.L_Teller));
33            dr["Account"= IcbcEtc.FormatAccount19(account);
34            dr["User"= customer;
35            dr["Flag"= (isDebit ? "" : "");
36            dr["Amt"= amt0;
37            dr["Memo"= Etc.Encode.GetString(bs,Pub.P_R2_Cashnote,Pub.L_Cashnote);
38            dr["Code"= code;
39            dr["TrName"= DbTrxCode.GetNewName(code);
40            dt.Rows.Add(dr);
41          }

42        }

43      }

44      DataView dv = dt.DefaultView;
45      dv.Sort = "Flag DESC, Amt DESC";
46      dgMain.DataSource = dv;
47      dgMain.DataBind();
48    }

49
posted on 2005-09-17 15:47 银河 阅读(2301) 评论(7)  编辑 收藏 所属分类: .NET Framework

评论

工商银行
  回复  引用  查看    

#2楼  2005-09-17 18:46 binking [未注册用户]
让人看得有点莫名其妙,重要的ZipInputStream类都不给出!
  回复  引用    

#3楼 [楼主] 2005-09-17 20:06 银河      
@binking:
> 让人看得有点莫名其妙,重要的ZipInputStream类都不给出!
不好意思,ZipInputStream 类是 ICSharpZipLib 开源类库中的类,下载地址如下:
http://www.icsharpcode.net/OpenSource/SharpZipLib/Download.aspx
其实在我的上一篇随笔《使用C#2.0进行文件压缩和解压》(http://www.cnblogs.com/skyivben/archive/2005/09/17/238828.html)
已经给出了这个下载地址。
  回复  引用  查看    

#4楼  2005-09-17 22:12 Jeky [未注册用户]
我觉得用ICSharpZipLib类进行文件解压缩不是很方便。
比如说要压缩一个文件夹,只能压缩它里面的子文件,而子文件夹却不能压缩。。
前段时间看灵感之源的blog上说ICSharpZipLib又出新版了,我没有下载,也不知道在这方面是否有所改进了。。。

我现在采用的方法是调用WinRar.Exe来在线解压缩,也蛮方便的。
我觉得比ICSharpZipLib好用。
  回复  引用    

#5楼 [楼主] 2005-09-18 14:39 银河      
@Jeky:
> 我觉得用ICSharpZipLib类进行文件解压缩不是很方便。
> 比如说要压缩一个文件夹,只能压缩它里面的子文件,而子文件夹却不能压缩。。


SharpZipLib是可以压缩子文件夹的, 以下是 SharpZipLib.chm 文档中的相关说明:
SharpZip Compression Library 
FastZip.CreateZip Method (String, String, Boolean, String, String)
Create a zip file.

public void CreateZip(
   string zipFileName,
   string sourceDirectory,
   bool recurse,
   string fileFilter,
   string directoryFilter
);
Parameters
zipFileName        The name of the zip file to create.
sourceDirectory   The directory to source files from.
recurse                True to recurse directories, false for no recursion.
fileFilter               The file filter to apply.
directoryFilter      The directory filter to apply.
可见, 只要将 FastZip.CreateZip() 方法的 recurse 参数设置为 true 就可以压缩子文件夹。

  回复  引用  查看    

#6楼 [楼主] 2005-09-19 18:50 银河      
后来,我把正文中最后一个程序中的第8行:
using (ZipInputStream zs = ...)
重构为:
using (Stream zs = ...)
这样,在该程序中就可以去掉下面这句话(在正文中的程序片断中没有列出来):
using ICSharpCode.SharpZipLib.Zip;

  回复  引用  查看    

#7楼  2006-05-22 12:56 tyfxzj [未注册用户]
我现在就写了一个压缩的事件,但就是只能压缩它里面的子文件,而子文件夹却不能压缩,你说将 FastZip.CreateZip() 方法的 recurse 参数设置为 true 就可以压缩子文件夹,这怎么改的啊,下面是我的程序:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.IO.Compression;
using System.ComponentModel;
using ICSharpCode.SharpZipLib.Checksums;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.GZip;
using System.Diagnostics;

namespace SharpZipLib
{

class Program
{
public void ZipFile(string FileToZip, string ZipedFile, int CompressionLevel, int BlockSize)
{
//如果文件没有找到,则报错
if (!System.IO.File.Exists(FileToZip))
{
throw new System.IO.FileNotFoundException("The specified file " + FileToZip + " could not be found. Zipping aborderd");
}

System.IO.FileStream StreamToZip = new System.IO.FileStream(FileToZip, System.IO.FileMode.Open, System.IO.FileAccess.Read);
System.IO.FileStream ZipFile = System.IO.File.Create(ZipedFile);
ZipOutputStream ZipStream = new ZipOutputStream(ZipFile);
ZipEntry ZipEntry = new ZipEntry("ZippedFile");
ZipStream.PutNextEntry(ZipEntry);
ZipStream.SetLevel(CompressionLevel);
byte[] buffer = new byte[BlockSize];
System.Int32 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 (System.Exception ex)
{
throw ex;
}
ZipStream.Finish();
ZipStream.Close();
StreamToZip.Close();
}

public void ZipFileMain(string[] args)//对文件进行压缩;
{
string[] filenames = Directory.GetFiles(args[0]);

Crc32 crc = new Crc32();
ZipOutputStream s = new ZipOutputStream(File.Create(args[1]));//新建压缩文件流 “ZipOutputStream”

s.SetLevel(6); // 0 - store only to 9 - means best compression

foreach (string file in filenames)
{
//打开要压缩的文件
FileStream fs = File.OpenRead(file);

byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
ZipEntry entry = new ZipEntry(file);

entry.DateTime = DateTime.Now;
entry.Size = fs.Length;
fs.Close();

crc.Reset();
crc.Update(buffer);

entry.Crc = crc.Value;

s.PutNextEntry(entry);

s.Write(buffer, 0, buffer.Length);

}
s.Finish();
s.Close();
}
public static string ServerDir;
static void Main(string[] args)
{
int month = Convert.ToInt32(DateTime.Now.ToString("MM"));//只取当前月份;
int iOldMonth = month - 1;
string a = iOldMonth.ToString();
string year = DateTime.Now.ToString("yyyy");//只取当前年份;
string time = Convert.ToString (year + "-" + a);
System.Console.WriteLine(time);
string abc = "c://unzipped/" + time;
string[] FileProperties = new string[2];
FileProperties[0] = abc;//待压缩文件目录
ServerDir = FileProperties[0];
//ServerDir = Path.GetDirectoryName(".");
System.Console.WriteLine(ServerDir);
FileProperties[1] = "C://zip/a.zip"; //压缩后的目标文件
Program Zc = new Program();
Zc.AddZipEntry(FileProperties);
}
请帮我改改,我这只能压缩它里面的子文件,而子文件夹却不能压缩,
请大哥帮忙,我很急,

  回复  引用    


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2005-10-07 17:56 编辑过
"五向定位"职业成长路线公开课(上海、南京、大连)
Google站内搜索


相关链接: