2012-07-17 13 views
6

MySQLデータベースからBLOBを読み取る際に問題が発生しています。私は正常にデータベースに挿入するためにそれを得たが、それを読み取るように見えることはできません。 「なぜファイルパス/ファイル名だけでなく、画像用のブロブを格納するためにデータベースを使用しているのですか」と考えている人もいるかもしれませんが、柔軟性を持たせたくあります。これは効率を最適化するだけでなく、必要に応じて画像をローカルに移動させることができます。私は(短い)チュートリアルに続き、以下のBLOBを受け取るためのメソッドを書いています。MySQLデータベースからBLOBイメージを読み取る

public void getBlob(string query, string fileOut) 
    { 
     if (this.OpenConnection() == true) 
     { 
      MySqlCommand cmd = new MySqlCommand(query, mConnection); 

      //the index number to write bytes to 
      long CurrentIndex = 0; 

      //the number of bytes to store in the array 
      int BufferSize = 100; 

      //The Number of bytes returned from GetBytes() method 
      long BytesReturned; 

      //A byte array to hold the buffer 
      byte[] Blob = new byte[BufferSize]; 


      //We set the CommandBehavior to SequentialAccess 
      //so we can use the SqlDataReader.GerBytes() method. 

      MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess); 

      while (reader.Read()) 
      { 
       FileStream fs = new FileStream(DeviceManager.picPath + "\\" + reader["siteBlobFileName"].ToString(), FileMode.OpenOrCreate, FileAccess.Write); 
       BinaryWriter writer = new BinaryWriter(fs); 
       CurrentIndex = 0; 
       BytesReturned = reader.GetBytes(1, CurrentIndex, Blob, 0,BufferSize); 

       while (BytesReturned == BufferSize) 
       { 
        writer.Write(Blob); 
        writer.Flush(); 
        CurrentIndex += BufferSize; 
        BytesReturned = reader.GetBytes(1, CurrentIndex, Blob, 0, BufferSize); 
       } 

       writer.Write(Blob, 0, (int)BytesReturned); 
       writer.Flush(); 
       writer.Close(); 
       fs.Close(); 
      } 
      reader.Close(); 

      this.CloseConnection(); 
     } 
    } 

などのように私はそれを呼んでいる。..

mDBConnector.getBlob("SELECT siteMapPicture, siteBlobFilename FROM sites WHERE siteID = '" + DeviceManager.lastSite + "'", DeviceManager.picPath + "mappicsite" + DeviceManager.lastSite); 


PBSite.BackgroundImage = Image.FromFile(DeviceManager.picPath + "mappicsite" + DeviceManager.lastSite); 

それはBytesReturned = reader.GetBytesにerroringだが(1、CurrentIndex、ブロブ、0、たBufferSize)。 「GetBytesはバイナリ列またはGUID列に対してのみ呼び出すことができます」というエラーが表示されます。私はこれが私のデータベースのフィールドの型と関係があると仮定していますが、カラムをバイナリ型に変更すると、それをBLOBソートとして格納する必要がありますが、ファイル名を通常の文字列のままにしておきたいのです。私は行方不明のものがありますか?またはこれを行う別の方法?

edit1:私は、bytesreturnedの最初のパラメータは読者の列と関係があると考えています。これを0に設定すると、「SequentialAccessを使用して前の列を読み込むのが無効です」というエラーが表示されます。

edit2:シーケンシャルアクセスを削除すると、サイズが13バイトのファイルが作成されます(最初の行になる可能性があるため、順次アクセスではすべての行が読み込まれます)。

編集3:このエラーの原因は、データベースに入力した方法によるものだと思います。この方法を変更した、私のsaveBlobは、今では次のようになります。

public void saveBlob(string filePath, string fileName, string siteID) 
    { 
     if (this.OpenConnection() == true) 
     { 

      //A stream of bytes that represnts the binary file 
      FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); 

      //The reader reads the binary data from the file stream 
      BinaryReader reader = new BinaryReader(fs); 

      //Bytes from the binary reader stored in BlobValue array 
      byte[] BlobValue = reader.ReadBytes((int)fs.Length); 

      fs.Close(); 
      reader.Close(); 


      MySqlCommand cmd = new MySqlCommand(); 
      cmd.Connection = mConnection; 
      cmd.CommandType = CommandType.Text; 
      cmd.CommandText = "INSERT INTO x (y, z) VALUES (@BlobFile, @BlobFileName)"; 

      MySqlParameter BlobFileNameParam = new MySqlParameter("@BlobFileName", SqlDbType.NChar); 
      MySqlParameter BlobFileParam = new MySqlParameter("@BlobFile", SqlDbType.Binary); 
      cmd.Parameters.Add(BlobFileNameParam); 
      cmd.Parameters.Add(BlobFileParam); 
      BlobFileNameParam.Value = fileName; 
      BlobFileParam.Value = BlobValue; 



       cmd.ExecuteNonQuery(); 

      this.CloseConnection(); 
     } 
    } 

私は、デバッガを駆け抜けてきた、との両方blobvalueとblobfileparam(@blobfileが)(150K程度)フルサイズを持っているが、それは実行時にerroringています次のエラーを返すクエリ。

​​

私はコードに見て取り、大きなファイルを許可するように、画像へのバイナリの種類を変更しようとしましたが、同じエラーを与えてきました。誰でもこの新しい情報について何か知っていますか?

edit 4:すべてを修正しました。私のコードでは、私が使用していたことに気づい:

("@BlobFile", SqlDbType.Binary); 

「MySqlDbType」(DERP)型にこれらを変更し、それは私がブロブの種類を選択することができました。物事は最終的に意図どおりに働いています:)

+1

は、私はC#の専門家だが、あなたは2列を選択している - 'siteMapPicture'と 'siteBlobFilename'を - 両方の塊であるか1でありますvarchar/char/text? –

+0

siteMapPictureはBLOBですが、siteBlobFilenameはvarcharです –

+0

開発者ではありませんが、BLOBフィールドはカラム#0ではありませんが、カラム1のgetbytesをパスフィールドにしようとしていますか? –

答えて

3

まず簡素化してみましたか?一度に100バイトのBLOBを読み込む代わりに、すべてのバイトをファイルに読み込むだけでコードを単純化してみてください。これにより、データレイヤの問題を簡単に排除できます。

は、以下の資料も、あなたが別の列としてファイルサイズを保存示唆:http://dev.mysql.com/doc/refman/5.5/en/connector-net-programming-blob.html

関連する問題