我最近要寫一個供有相關權限的管理人員查詢大額資金明細的程序,界面如下:
所需的數據文件是放在報表服務器上,每天一個壓縮文件,該壓縮文件中除了所需的儲蓄流水賬文件外,還有很多其他的文件。如果先把該壓縮文件從報表服務器下載到應用服務器上,再進行解壓縮處理的話,一是多下載了該壓縮文件中我們不需要的其他文件,二是還必須在應用服務器上建立以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[]中去,這樣就取得了我們所需的數據,就象儲蓄流水賬文件就存放在本地硬盤上一樣,避免了下載文件和解壓文件。具體代碼如下:
1

using System;
2

using System.IO;
3

using System.Net;
4
5

namespace 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 == -1) break;
40

bw.Write((byte)c);
41

}
42

}
43

}
44

}
45

}
46

}
47

1

using System;
2

using System.IO;
3

using ICSharpCode.SharpZipLib.Zip;
4
5

namespace 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 <= 0) break;
17

offset += size;
18

count -= size;
19

} while (count > 0);
20

if (count != 0) throw 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)) < 0) continue;
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 <= 0) break;
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 != 0) throw 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
