2017年9月17日 星期日

ASP.NET FileUpload.PostedFile.InputStream + MemoryStream儲存檔案

參考資料1:How to Save the MemoryStream as a file in c# and VB.Net

Web.config
<?xml version="1.0"?>
<configuration>
    <!--這裡自己加入appSettings標籤以及FileUpload_path1-->
    <appSettings>
      <add key="FileUpload_path1" value="~/FileUpload/File1/" />
    </appSettings>
    ....
</configuration>

Default.aspx
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        使用FileUpload.PostedFile.InputStream + MemoryStream儲存檔案<br/>
        <asp:FileUpload ID="FileUpload2" runat="server" />
        <asp:Button ID="Button2" runat="server" Text="Start Upload2" />
        <br/>
        <asp:Label ID="Label2" runat="server"></asp:Label>
    </div>
    </form>
</body>
</html>

Default.aspx.vb
Imports System.IO
Imports System.Web.Configuration

Partial Class _Default
    Inherits System.Web.UI.Page

    Function EnMD5(ByVal EnString As String, Optional ByVal substring_startIndex As Integer = 8, Optional ByVal select_length As Integer = 16) As String
        Dim str_En As String = Nothing
        If select_length = 16 Then
            str_En = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(EnString, "MD5").ToLower().Substring(substring_startIndex, select_length)
        ElseIf select_length = 32 Then
            str_En = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(EnString, "MD5").ToLower()
        Else
            str_En = "0"
        End If
        Return str_En
    End Function

    Protected Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        If Not FileUpload2.PostedFile Is Nothing Then
            Try
                If FileUpload2.HasFile And FileUpload2.PostedFile.ContentLength > 0 Then
                    Dim filetype As String = Nothing
                    Dim bool_by As Boolean = True
                    Dim str_DirPath As String = String.Empty
                    If (Not WebConfigurationManager.AppSettings("FileUpload_path1") Is Nothing) Then

                        str_DirPath = Server.MapPath(WebConfigurationManager.AppSettings("FileUpload_path1").ToString())
                        If Directory.Exists(str_DirPath) = False Then '檢查目錄存不存在
                            '不存在就建立資料夾
                            Directory.CreateDirectory(str_DirPath)
                        End If
                        '====================================
                        Dim s As Stream = FileUpload2.PostedFile.InputStream
                        Dim file_bytes(s.Length - 1) As Byte
                        s.Read(file_bytes, 0, s.Length)

                        Dim header As String = Hex(file_bytes(0)) & Hex(file_bytes(1)) & Hex(file_bytes(2)) & Hex(file_bytes(3))
                        '檢查檔案格式
                        Select Case header
                            Case "FFD8FFE0" '*.jfif *.jpe *.jpeg *.jpg
                                '假如是用小畫家製作的圖或另存的圖檔,header值會是FFD8FFE0,但如果是其他方式產生的jpg圖檔最後一碼會變動
                                filetype = "jpg"
                            Case "25504446"
                                filetype = "pdf"
                            Case "D0CF11E0"
                                filetype = "doc"
                            Case "504B34"
                                filetype = "docx"
                            Case Else
                                bool_by = False
                        End Select
                        '=====================================
                        If bool_by = True Then
                            '====================================
                            Dim myFileName As String
                            myFileName = FileUpload2.PostedFile.FileName
                            Dim c As String = String.Empty  '取得檔案及副檔名System.IO.Path.GetFileName(myFileName)
                            filetype = myFileName.Substring(myFileName.LastIndexOf(".") + 1)

                            '=========================================
                            Dim str_temp_fn As String = String.Empty
                            '用MD5來作檔案名稱
                            str_temp_fn = EnMD5("FU_PATH1_" & Date.Now.ToString("yyyyMMddHHmmssffff"), select_length:=32)
                            Dim Uploadfile As String = String.Empty
                            '重新命名
                            c = str_temp_fn & "." & filetype 'MD5命名
                            Uploadfile = str_DirPath & c
                            Dim myfilecount As Integer = 1
                            '檢查檔名是否有重複
                            While (System.IO.File.Exists(Uploadfile))
                                '有重複的檔案從2開始
                                myfilecount = myfilecount + 1
                                c = str_temp_fn & myfilecount & "." & filetype  'MD5命名 + 第幾個檔案
                                Uploadfile = str_DirPath & c '重新命名並加上副檔名
                            End While
                            '==========================================
                            Dim ms As New MemoryStream(file_bytes)
                            Dim fs2 As New FileStream(Uploadfile, FileMode.Create, FileAccess.Write)
                            ms.WriteTo(fs2)
                            fs2.Close()
                            ms.Close()
                            '==========================================
                            Label2.Text = Uploadfile
                        Else
                            Label2.Text = "檔案格式不符"
                        End If
                        s.Close()
                        s.Dispose() '釋放所有資源要在最後執行,否則即使存檔也無效

                    End If
                Else
                    Label2.Text = "請選擇檔案"
                End If
            Catch ex As Exception
                Label2.Text = ex.ToString
            End Try
        Else
            Label2.Text = "請選擇檔案"
        End If
    End Sub
End Class