से BLOB छवि पढ़ने के लिए मुझे एक MySQL डेटाबेस से वापस ब्लॉब पढ़ने में कुछ परेशानी हो रही है। मैं इसे डेटाबेस में सफलतापूर्वक सम्मिलित करने के लिए प्राप्त कर लिया है, लेकिन इसे वापस पढ़ने के लिए प्रतीत नहीं होता है। मुझे पता है कि आप में से कुछ सोच रहे होंगे "वह छवियों के लिए ब्लॉब्स स्टोर करने के लिए डेटाबेस का उपयोग क्यों कर रहा है, न केवल फाइल पथ/फ़ाइल नामों", लेकिन मैं लचीलापन चाहता हूं और इन छवियों में से कई को संग्रहीत किया जाएगा सर्वर और स्थानीय रूप से नहीं, यह दक्षता को अनुकूलित करता है, साथ ही मुझे आवश्यक होने पर छवियों को स्थानांतरित करने की इजाजत देता है। मैंने एक (लघु) ट्यूटोरियल का पालन किया है और ब्लॉब प्राप्त करने के लिए यह निम्न विधि लिखी है;MySQL डेटाबेस
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 कॉलम पर बुलाया जा सकता है"। मुझे लगता है कि यह मेरे डेटाबेस में मेरे क्षेत्र के प्रकार के साथ करना है, लेकिन बाइनरी टाइप करने के लिए कॉलम को बदलना है, मुझे उसे ब्लॉब प्रकार के रूप में स्टोर करना होगा, लेकिन मैं फ़ाइल नाम को नियमित स्ट्रिंग के रूप में छोड़ना चाहता हूं। क्या मुझे कुछ याद आ रहा है? या ऐसा करने का एक और तरीका?
संपादित 1: मुझे लगता है कि बाइट्सट्रर्न के लिए पहला पैरामीटर पाठक में कॉलम के साथ करना है, इसे 0 पर सेट करने से त्रुटि "अनुक्रमिक पहुँच का उपयोग करके पूर्व कॉलम पढ़ने का अमान्य प्रयास" है, बीमार इसे देखें।
संपादित 2: अनुक्रमिक पहुंच को हटाने से मुझे आकार 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 है क्वेरी, निम्नलिखित त्रुटि दे रही है;
"unable to cast object of type 'system.byte[]' to type 'system.iconvertible"
मैं कोड में एक नज़र लिया है और छवि के लिए द्विआधारी प्रकार बदलने के लिए, बड़ी फ़ाइलों को अनुमति देने के लिए करने की कोशिश की, लेकिन एक ही त्रुटि देता है। किसी को भी इस नई जानकारी के बारे में कुछ पता है?
संपादित करें 4: निश्चित सब कुछ। देखा है कि मेरी कोड में मैं उपयोग कर रहा था:
("@BlobFile", SqlDbType.Binary);
प्रकार "MySqlDbType" करने के लिए इन बदल दिया (Derp) और यह मेरे ब्लॉब के प्रकार का चयन करने की अनुमति दी। चीजें अंततः इरादे के रूप में काम कर रही हैं:)
मैं कोई सी # विशेषज्ञ हूँ, लेकिन आप 2 कॉलम चयन कर रहे हैं - '' siteMapPicture और 'siteBlobFilename' - दोनों धब्बे हैं या एक है varchar/चार/पाठ? –
साइटमैपचित्र एक बीएलओबी है, साइटब्लोबफिलनाम एक वर्कर –
एक सी # डेवलपर नहीं है, लेकिन क्या आपका ब्लॉब फ़ील्ड कॉलम # 0 नहीं होगा, जबकि आप कॉलम # 1 पर गेटबाइट्स करने का प्रयास कर रहे हैं, जो पथ फ़ील्ड होगा? –