Open File Stream Win API - PullRequest
       48

Open File Stream Win API

2 голосов
/ 17 января 2010

Я пытаюсь использовать инструкцию

OpenSqlFilestream

, но мой код не распознал ее

Какую DLL мне нужно загрузить, чтобы использовать ее?


Уважаемый marc_s посмотрите на мой код

Public Sub WriteFileStream(ByVal imSource As Byte(), ByVal imSize As Integer, ByVal imTy As Type, ByVal sender As Object, ByVal e As EventArgs)
    Dim subProvider As String = Nothing
    Dim subDataSource As Object = Nothing
    Dim subUid As String = Nothing
    Dim subPwd As String = Nothing
    Dim subDataBase As String = Nothing
    Dim subPSI As Boolean = Nothing
    Dim ParamXML() As String = Nothing
    Dim TypeOfServer As String = "Remote"
    Dim imParam(3) As String
    Dim imTable(1) As String
    Dim RemoteSQLcmd As SqlCommand = New SqlCommand
    Dim tokenReader As SqlDataReader
    '-------------------------------------------------'

    Dim AbsRecord As Int64 = 0
    Dim VarString(10) As String
    Dim VarInt(10) As Integer
    '-------------------------------------------------'
    ParamXML = Split(loadXmlFile(TypeOfServer, sender, e), "|")
    subUid = ParamXML(3)
    subProvider = ParamXML(0)
    subDataSource = ParamXML(1)
    subDataBase = ParamXML(2)
    subPwd = ParamXML(4)
    subPSI = ParamXML(5)

    Dim SchemaID As String = Convert.ToInt16(ParamXML(8))
    Dim SchemaName As String = Nothing
    If SchemaID = 1 Then
        SchemaName = subUid
    ElseIf SchemaID = 2 Then
        SchemaName = "dbo"
    ElseIf SchemaID = 0 Then
        SchemaName = "dbo"
    End If
    '-------------------------------------------------'
    imTable(0) = "tPDetails"
    imTable(1) = "tPImages"
    Try
        imParam(0) = Me.TextBox1.Text.Trim.ToString     'Name'
        imParam(1) = Me.TextBox2.Text.Trim.ToString     'Code'
        imParam(2) = Me.TextBox3.Text.Trim.ToString     'Price'
        imParam(3) = Me.TextBox4.Text.Trim.ToString     'Comments'
        '========================================================'
    If RemoteSQLConn.State = ConnectionState.Open Then RemoteSQLConn.Close()
    SQL_Connection(TypeOfServer, TypeOfServer & "Conn.xml", sender, e)
    RemoteSQLConn.open()

        '----------------------'
        Dim imHolder As Image = Image.FromStream(imStream)
        Dim imHeight As Integer = imHolder.Height
        Dim imWidth As Integer = imHolder.Width
        Dim imLength As Integer = imHolder.PropertyItems.Length
        Dim imType As Type = imTy
        '----------------------'
        Dim FirstColumnNames As String = _
                                imTable(0) & "_Code, " & _
                                imTable(0) & "_Price, " & _
                                imTable(0) & "_Title, " & _
                                imTable(0) & "_Type, " & _
                                imTable(0) & "_Height, " & _
                                imTable(0) & "_Width, " & _
                                imTable(0) & "_Stock, " & _
                                imTable(0) & "_Comments "
        Dim FirstFieldsValues As String = "'" & imParam(1) & "', '" & _
                                imParam(2) & "', '" & _
                                imParam(0) & "', '" & _
                                imType.ToString & "', '" & _
                                imHeight & "', '" & _
                                imWidth & "', '" & _
                                "0', '" & _
                                imParam(3) & "' "
'--------------------------------------------'
           RemoteSQLcmd = New SqlCommand("INSERT INTO " & _
    SchemaName & "." & imTable(0) & " (" & FirstColumnNames & ")                     VALUES (" & FirstFieldsValues & ") ", RemoteSQLConn)
            RemoteSQLcmd.ExecuteNonQuery()
            '--------------------------------------------------'
    RemoteSQLcmd = New SqlCommand("SELECT * FROM " & SchemaName & "." & imTable(0) & _
    " WHERE " & imTable(0) & "_Code = " & "'" & imParam(1) & "'", RemoteSQLConn)
            AbsRecord = RemoteSQLcmd.ExecuteScalar
            '--------------------------------------------------'
      RemoteSQLcmd = New SqlCommand("INSERT INTO " & SchemaName & "." & imTable(1) & " VALUES (newid(), " & AbsRecord & ", CAST('' as varbinary(max)))", RemoteSQLConn)

            RemoteSQLcmd.ExecuteNonQuery()
            '--------------------------------------------------'
    RemoteSQLcmd = New SqlCommand("SELECT " & imTable(1) & "_Image.PathName() FROM " & _
SchemaName & "." & imTable(1) & " WHERE " & imTable(1) & "_" & imTable(0) & "_ID = " & AbsRecord, RemoteSQLConn)
            Dim filePathName As String = Nothing
            Dim pathObj As Object = RemoteSQLcmd.ExecuteScalar()
'--------------------------------------------------   Path Name  '
            If Not pathObj.Equals(DBNull.Value) Then
                filePathName = DirectCast(pathObj, String)
            Else
    Throw New System.Exception("Image.PathName() failed to read the path name for the Image column.")
            End If
    '--------------------------   GET_FILESTREAM_TRANSACTION_CONTEXT()'
            Dim RemoteSQLtx As SqlTransaction = RemoteSQLConn.BeginTransaction("MainTranaction")
            RemoteSQLcmd.Transaction = RemoteSQLtx
    RemoteSQLcmd = New SqlCommand("SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()", RemoteSQLConn, RemoteSQLtx)
            Dim tokenObject As Object = RemoteSQLcmd.ExecuteScalar()
        '--------------------------------------   File Token '
            tokenReader = RemoteSQLcmd.ExecuteReader(CommandBehavior.SingleRow)
            tokenReader.Read()
            Dim txContext As SqlBinary = DirectCast(tokenObject, Byte())
            tokenReader.Close()
            '-----------------------------------------------'
            Try
                '--------------------  Closing all connections'
       If RemoteSQLConn.State = ConnectionState.Open Then RemoteSQLConn.Close()
       If RemoteSQLcmd.Connection.State = ConnectionState.Open Then RemoteSQLcmd.Connection.Close()
                If RemoteConnInfo.State = ConnectionState.Open Then RemoteConnInfo.Close()
                RemoteSQLtx.Dispose() '.Connection.State = ConnectionState.Open Then RemoteSQLtx.Connection.Close()
       '--------------------  Open connections for Indegrated Security''
                ChangeLoginPerson("PRINCIDEVEL\Administrator")
                RemoteConnInfo.ConnectionString = "Provider=" & subProvider & "; Data Source=" & subDataSource & _
                "; Database=" & subDataBase & "; Integrated Security=" & "SSPI" & "; Persist Security Info=" & subPSI
                RemoteSQLcmd.Connection.Open()
                RemoteSQLConn = New SqlConnection("Server=" & subDataSource & "; Integrated Security=TRUE" & "; database=" & subDataBase)
                RemoteSQLConn.Open()
                RemoteSQLtx = RemoteSQLConn.BeginTransaction("MainTranaction")
                RemoteSQLcmd.Transaction = RemoteSQLtx
                '-------------------------  Write in to file stream   ---------------'
                Dim imImage As Byte() = New Byte(imStream.Length) {}
                Dim bytesRead As Integer = imStream.Read(imImage, 0, imStream.Length)
                Dim sqlFile As New SqlFileStream(filePathName, txContext, FileAccess.ReadWrite, FileOptions.WriteThrough, 0)
                Dim numBytes As Integer = 0
                Dim unicode As Encoding = Encoding.GetEncoding(0)
                While bytesRead > 0
                    sqlFile.Write(imImage, 0, bytesRead)
                    bytesRead = imStream.Read(imImage, 0, imSize)
                End While
                RemoteSQLtx.Commit()
                RemoteSQLcmd.Transaction.Commit()
                sqlFile.Close()
            Catch FsEx As Exception
                MessageBox.Show(FsEx.Message, "Write in SQL File Stream ", MessageBoxButtons.OK, MessageBoxIcon.Stop)
            Finally
            End Try
            '--------------------------------------------------'
        Catch ex As Exception
MessageBox.Show(ex.Message, "WriteFileStream ", MessageBoxButtons.OK, MessageBoxIcon.Stop)
            Finalize()
        Finally
            RemoteSQLConn.Close()
            imStream.Close()
        End Try


    End Sub

1 Ответ

2 голосов
/ 17 января 2010

Делаете ли вы все необходимые шаги перед открытием файлового потока? Захватить контекст внутри транзакции ??

Проверьте эту статью здесь для подробного обсуждения того, как это сделать. Вот еще одно сообщение в блоге с примером кода VB.NET.


Обновление: Лефтерис, ваш фрагмент кода очень очень трудно прочитать и понять, я сделал все возможное, но я действительно не уверен. Я думаю, что вы слишком быстро закрываете транзакцию. Вы, кажется, создаете соединение и транзакцию, чтобы получить GET_FILESTREAM_TRANSACTION_CONTEXT, но затем закрываете это снова, прежде чем фактически записать свои байты. Я думаю, что транзакция должна охватывать все операции - она ​​должна начаться до того, как вы получите контекст транзакции, и она должна остаться в живых для всей операции записи и быть зафиксированной только после завершения всей операции записи.

Я попытался придумать более простой фрагмент кода, чтобы показать вам - это на C #, поскольку я не смог преобразовать его обратно в VB.NET:

public static void WriteFileStream(byte[] imSource, int imSize)
{ 
   // use your own SQL insert command here instead
   const string InsertCmd = "INSERT INTO PhotoAlbum(PhotoId, Description)" +
          " VALUES(@PhotoId, @Description)";

   using (SqlConnection conn = new SqlConnection(ConnStr))
   {
       conn.Open();

       // create transaction here and let it stay alive!
       using (SqlTransaction txn = conn.BeginTransaction())
       {
            using (SqlCommand cmd = new SqlCommand(InsertCmd, conn, txn))
            {
               cmd.Parameters.Add("@PhotoId", SqlDbType.Int).Value = photoId;
               cmd.Parameters.Add("@Description", SqlDbType.VarChar).Value = desc;
               cmd.ExecuteNonQuery();
            }

            SafeFileHandle handle = GetOutputFileHandle(photoId, txn);

            MemoryStream inputStream = new MemoryStream(imSource);

            using (FileStream dest = new FileStream(handle, FileAccess.Write))
            {
               byte[] buffer = new byte[BlockSize];
               int bytesRead;

               while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) > 0)
               {
                   dest.Write(buffer, 0, bytesRead);
               }
               dest.Close();
            }

            inputStream.Close();

            // commit transaction here, after all is done                
            txn.Commit();
        }
        conn.Close();
    }
}

Это адаптировано из сообщения в блоге SQL Server 2008 FILESTREAM, часть 3: OpenSqlFileStream API - проверьте это всеми средствами!

...