緣起:
這幾天在看我們程式的信箱功能程式碼,注意到它有上傳附件的功能,上傳完的附件會傳到後台,還會專門開個資料夾放那些附件。蠻特別的,它不是傳到
ws 主機,然後再把檔案路徑記到資料表。
我注意到在上傳檔案的部份,它有用到
Request.Files 來取得使用者上傳的檔案,然後讀取檔案、把檔案給寫到 Server
端的資料夾的部份則是用到 C# 的 Stream。覺得這些功能蠻實用的,而且自己好像也還沒實際寫過從前台上傳檔案到 Server
的程式,所以就試著寫了一次,順便紀錄。
C# FileStream:
公司專案有個 Tools 類別,它有個 static 方法,叫
CopyStream,大概長這樣
功能就是複製一個 Stream 的內容到另一個 Stream,我開個 Console 專案測試,程式碼如下,用 FileStream 來讀取程式檔前路徑下的 txt 檔,然後把內容給 Copy 到 MemoryStream 裡,然後一個 byte 一個 byte 輸出
那個 test.txt 是放在專案的 bin/Debug 下,內容就
"Hello"
我不確定為啥 CopyStream 的 buffer size
是開 1024*16,有特別去查了一下,就我的理解,回答是說,沒有特別需求的話,開到 4K 或以上似乎就行,開到
16 K 的話就有點浪費記憶體了。
我後來發現,Stream 類別自己就有個
CopyTo
的方法可以使用,把自己的內容給複製到另一個 Stream 裡。我有試著呼叫
fileStream 的 CopyTo 方法,把內容給複製到
memoryStream,結果是一樣的,所以,不太清楚為什麼我們公司的專案還有特別寫了一個方法來做這件事。
Request.Files:
再來是開個 ASP
專案測試擷取檔案上傳的部份,我在新開的專案下新增一個 test asp 頁面。
這是它的 aspx,有三個元件,上傳檔案的
input,顯示一些資訊的 label,還有一個 button。
然後這是它的 cs,我第一步是先測試是否真的有從 Request.Files 取到上傳的檔案,它是一個 HttpFileCollection 類別,既然是
Collection,那基本上都會有個 Count
來記錄有多少個成員,所以這邊的程式碼是,點了 button 後,顯示上傳檔案的數量
build 完程式,用 iis express 來看我們的 test.asp
頁面會是這樣。
16 行 : 可以用 Server.MapPath 來取得實體路徑,那個 /upload 就是我要放上傳檔的資料夾。
17、18行 : 確認資料夾是否有存在,沒的話建立一個。
22 行 : for 迴圈遊歷 HttpFileCollection,我原本以為可以用 foreach 來做的,但後來發現不行。原來用 foreach 會取到它檔案的名字,是 string,正確做法是用存取陣列的方式來取得每個 HttpPostedFile
25 行 : 檢查,避免空的檔案。
27 行 : 把上傳路徑跟檔案名稱組起來,要給 FileStream constructor 用的路徑。
28 ~ 31 行 : 依路徑開啟 FileStream,然後從 httpPostedFile.InputStream 來取得檔案的 Stream,用 CopyTo 把內容給複製到 fileStream。
這樣就可以了,一樣測試上傳兩張圖片,按完 "上傳" 後,可以發現專案資料夾下面有多一個 upload 的資料夾,點開來看,可以看到兩張上傳的圖片。
沒有留言:
張貼留言