国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > .NET > 正文

在ASP.NET中動(dòng)態(tài)修改文件下載

2024-07-10 12:57:14
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
引言

我們常常需要給我們的客戶提供下載鏈接,這個(gè)鏈接必須允許每一個(gè)客戶根據(jù)他們例如像前一步輸入的帳號(hào)或其他注冊(cè)信息
下載相關(guān)的文件。網(wǎng)頁(yè)有下列接口:在第一個(gè)網(wǎng)頁(yè)中用戶必須輸入用戶名,而在下一個(gè)網(wǎng)頁(yè)中我們?yōu)檫@個(gè)用戶提供下載應(yīng)用程序復(fù)本的鏈接。一旦用戶下載應(yīng)用程序并啟動(dòng)了它,他會(huì)看到帶有他的名字的“歡迎”窗口,這個(gè)窗口由第一個(gè)網(wǎng)頁(yè)指定。
有很多方法可以實(shí)現(xiàn)這樣的功能。一個(gè)方法是使用從服務(wù)器傳送到客互端的用戶名信息修改或重編譯可下載的應(yīng)用程序/包。
這個(gè)任務(wù)可以通過(guò)簡(jiǎn)單的步驟實(shí)現(xiàn)它:

將可下載的文件裝載到內(nèi)存。
用新的值替換指定位置的指定數(shù)量的字節(jié)。
結(jié)合并發(fā)送修改過(guò)的文件數(shù)據(jù)響應(yīng)給客戶端。
讓我們繼續(xù)瀏覽一下每一個(gè)步驟。

定制下載過(guò)程

為了實(shí)現(xiàn)可下載資源的定制動(dòng)作,我們可以使用按鈕或鏈接按鈕控件,它們?cè)试S你為控件的點(diǎn)擊動(dòng)作實(shí)現(xiàn)服務(wù)器端代碼。
整個(gè)過(guò)程有兩步組成:結(jié)合網(wǎng)絡(luò)響應(yīng)流和提供這個(gè)響應(yīng)一個(gè)正確的http頭。服務(wù)器響應(yīng)流表示要被發(fā)送至網(wǎng)絡(luò)客戶端的文件數(shù)據(jù)。為了提供給這個(gè)網(wǎng)絡(luò)客戶端傳輸?shù)奈募蚼ime內(nèi)容類型等信息,我們必須將這些信息插入到http頭的字段中作為響應(yīng)。
下面的代碼演示了怎樣加載服務(wù)器上的文件使生成文件流,并保存到http響應(yīng)流中。
private void lnkdownload_click(object sender, system.eventargs e) {
filestream stream = new filestream(server.mappath("testdownload.exe"), filemode.open,
fileaccess.read, fileshare.read);
try {
int bufsize = (int)stream.length;
byte[] buf = new byte[bufsize];

int bytesread = stream.read(buf, 0, bufsize);

response.outputstream.write(buf, 0, bytesread);
response.end();
}
finally {
stream.close();
}
}
根據(jù)rfc 2616 和 rfc 1806 我們需要指出content-type 和 content-disposition 文件頭字段是通過(guò)下列信息來(lái)傳輸二進(jìn)制數(shù)據(jù)的。
response.contenttype = "application/octet-stream";
response.appendheader("content-disposition", "attachment;filename=" + "testdownload.exe");
在將數(shù)據(jù)寫進(jìn)http響應(yīng)流之前,請(qǐng)先寫這段代碼。

修改文件

決定二進(jìn)制數(shù)據(jù)需要修改的位置有些困難。如果你有一個(gè)普通的可執(zhí)行應(yīng)用文件在固定的位置能夠包含可執(zhí)行的資源或是在隨機(jī)的位置包含代碼。這大多數(shù)取決于你所要完成的任務(wù)并能根據(jù)不同的可下載文件作出改變。其他解決方案是用參數(shù)初始化批文件并使用定制的參數(shù)來(lái)重新編譯你的應(yīng)用程序或包。
假設(shè)我們發(fā)現(xiàn)文件內(nèi)正確的位置并且需要用用戶輸入的新數(shù)據(jù)替換原始內(nèi)容:
private void patchdata(byte[] buf, string username, int position) {
byte[] patch = encoding.unicode.getbytes(username);
system.array.copy(patch, 0, buf, position, patch.length);
}
我們同時(shí)假設(shè)文件不是很大,能夠被加載到單個(gè)內(nèi)存緩沖區(qū)中。
因?yàn)榭上螺d的可執(zhí)行文件也許會(huì)經(jīng)常被重新編譯和替換,填充的位置也經(jīng)常改變。所以不要將這些參數(shù)在asp.net dll代碼中進(jìn)行硬編碼而是將它們放入如web.config文件中將是非常明智的。
private void lnkdownload_click(object sender, system.eventargs e) {
string filename = configurationsettings.appsettings["filename"];
int position = convert.toint32(configurationsettings.appsettings["position"]);

filestream stream = new filestream(server.mappath(filename), filemode.open,
fileaccess.read, fileshare.read);
try {
response.contenttype = "application/octet-stream";
response.appendheader("content-disposition", "attachment;filename=" + filename);

int bufsize = (int)stream.length;
byte[] buf = new byte[bufsize];

int bytesread = stream.read(buf, 0, bufsize);

patchdata(buf, edtusername.text, position);

response.outputstream.write(buf, 0, bytesread);
response.end();
}
finally {
stream.close();
}
}

源代碼和運(yùn)行例子

目前實(shí)現(xiàn)的這個(gè)版本有一個(gè)限制——為了簡(jiǎn)化這個(gè)demo,我們沒(méi)有實(shí)現(xiàn)續(xù)載的功能。一旦如果你的文件大了,你也許想要改變這樣的行為并增加支持續(xù)傳。為了實(shí)現(xiàn)實(shí)現(xiàn)隨即資源的訪問(wèn)功能,你需要分析文件頭請(qǐng)求字段的范圍。通過(guò)這個(gè)請(qǐng)求客戶端指定他們需要下載的資源的字節(jié)范圍。范圍字段可以有1個(gè)或2個(gè)數(shù)字組成,如1024-23544。這表示客戶端將要接收1024到23544字節(jié)間包含的字節(jié)數(shù)。參見(jiàn)hypertext transfer protocol rfc文檔獲得更多關(guān)于網(wǎng)絡(luò)范圍請(qǐng)求的信息。
這段代碼將不斷的優(yōu)化和改進(jìn),我們隨時(shí)歡迎你的評(píng)論和建議。



發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 呈贡县| 天柱县| 靖西县| 顺平县| 湘潭县| 内黄县| 鄯善县| 泸西县| 南溪县| 特克斯县| 通山县| 如东县| 台中县| 潼南县| 太仆寺旗| 武陟县| 沈丘县| 特克斯县| 高平市| 积石山| 通江县| 湖州市| 大英县| 饶阳县| 故城县| 宜章县| 方山县| 富宁县| 潢川县| 宜阳县| 和政县| 偃师市| 麟游县| 西青区| 河西区| 册亨县| 项城市| 德令哈市| 正阳县| 中宁县| 新干县|