日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Oracle中利用BLOB字段存儲4GB以下視頻數(shù)據(jù)

很長時間沒親自寫寫東西了,只是收集轉(zhuǎn)載了一些好資料,其實,真正靜下心總結(jié)一下,可以寫的知識點很多。與困難做斗爭,挑戰(zhàn)技術(shù)難關(guān),總會有些感受心得的。

今天想和網(wǎng)友分享一下“Oracle中BLOB大字段如何讀寫視頻數(shù)據(jù)”,這個話題起因是我在使用ORACLE備份數(shù)據(jù)時,誤刪了數(shù)據(jù)庫實例的控制文件,導(dǎo)致項目數(shù)據(jù)需要重新入庫。也就是我在彌補(bǔ)這個錯誤時,發(fā)現(xiàn)之前的數(shù)據(jù)入庫功能,都沒有把200M以上的視頻數(shù)據(jù)導(dǎo)入ORACLE的BLOB字段里,也就是之前的寫入BLOB字段數(shù)據(jù)的方法失效了。這是個驚人的發(fā)現(xiàn),我發(fā)現(xiàn)因為這個程序BUG我遺漏掉近300G的視頻數(shù)據(jù),某些單個視頻文件數(shù)據(jù)量達(dá)到3.6G。

我研究基于ORACLE Text的全文檢索功能,開始接觸ORACLE的BLOB字段,3年多了,自認(rèn)為已經(jīng)熟知BLOB字段的操作。但這次的難題迫使我更深入的認(rèn)識ORACLE的BLOB字段。

BLOB字段能以二進(jìn)制形式存放4G數(shù)據(jù),200M的視頻數(shù)據(jù)當(dāng)然應(yīng)該沒問題,可以出錯了?!原來的方法會報“Out of memory”錯誤,PLSQL Developer工具導(dǎo)入大視頻數(shù)據(jù),同樣會報“Out of memory”錯誤。3.6G的視頻數(shù)據(jù)又該如何導(dǎo)入?原來寫入大字段的方法,導(dǎo)入一般的圖片和文檔一點問題沒有。

 
 
 
  1. ///   
  2. /// 寫大字段內(nèi)容  
  3. /// (新方法,2010.2.4)  
  4. ///   
  5. ///   
  6. ///   
  7. ///   
  8. ///   
  9. ///   
  10. ///   
  11. public bool WriteBlobField(System.Data.OleDb.OleDbConnection pDbConn,  
  12.     string strTable,  
  13.     string strBlobField,  
  14.     string strFile,  
  15.     string strWhereClause)  
  16. {  
  17.     if (strWhereClause == "")  
  18.     {  
  19.         return false;  
  20.     }  
  21.     try 
  22.     {  
  23.         string strSQL = "UPDATE " + strTable + " SET " + strBlobField + " =:blob WHERE " + strWhereClause;  
  24.  
  25.         OleDbCommand cmd = new OleDbCommand(strSQL, pDbConn);  
  26.         //無需說明類型  
  27.         //cmd.Parameters.Add(new OleDbParameter("blob", SqlDbType.VarBinary));  
  28.         // cmd.Parameters.AddWithValue("blob", SqlDbType.Binary);  
  29.         FileInfo fileInfo = new FileInfo(strFile);  
  30.  
  31.         FileStream fsBlob = fileInfo.OpenRead();// new FileStream(strFile, FileMode.Open,FileAccess.Read);  
  32.         byte[] dataBlob = new byte[fsBlob.Length];//問題1所在  
  33.         fsBlob.Read(dataBlob, 0, System.Convert.ToInt32(fsBlob.Length));//問題2所在  
  34.         fsBlob.Close();  
  35.         //采用新的方法,AddWithValue();  
  36.         cmd.Parameters.AddWithValue("blob", dataBlob);  
  37.         //cmd.Parameters["blob"].Value = dataBlob;  
  38.         int result = cmd.ExecuteNonQuery();  
  39.         if (result < 1)  
  40.         {  
  41.             return false;  
  42.         }  
  43.     }  
  44.     catch (Exception ex)  
  45.     {  
  46.         //   MessageBox.Show(ex.Message, "寫數(shù)據(jù)", MessageBoxButtons.OK);  
  47.         return false;  
  48.     }  
  49.  
  50.     return true;  
  51. }  
  52.  
  53.     ///   
  54.     /// 將字符串寫成大字段內(nèi)容  
  55.        /// (2010.2.4 修改)  
  56.     ///   
  57.     ///   
  58.     ///   
  59.     ///   
  60.     ///   
  61.     ///   
  62.     ///   
  63.     public bool WriteBlobField2(System.Data.OleDb.OleDbConnection pDbConn,  
  64.                   string strTable,  
  65.                  string strBlobField,  
  66.                  string strBlobContent,  
  67.                  string strWhereClause)  
  68.     {  
  69.         if (strWhereClause == "")  
  70.         {  
  71.             return false;  
  72.         }  
  73.  
  74.         try 
  75.         {  
  76.             string strSQL = "UPDATE " + strTable + " SET " + strBlobField + " =:blob " +  
  77.                 "WHERE " + strWhereClause;  
  78.  
  79.             OleDbCommand cmd = new OleDbCommand(strSQL, pDbConn);  
  80.             cmd.Parameters.Add(strBlobField, SqlDbType.Binary);  
  81.             //    byte[] dataBlob = new byte[strBlobContent.Length];  
  82.             byte[] dataBlob = System.Text.Encoding.Default.GetBytes(strBlobContent);  
  83.             cmd.Parameters["blob"].Value = dataBlob;  
  84.             int result = cmd.ExecuteNonQuery();  
  85.             if (result < 1)  
  86.             {  
  87.                 return false;  
  88.             }  
  89.         }  
  90.         catch (Exception ex)  
  91.         {  
  92.             MessageBox.Show(ex.Message, "寫數(shù)據(jù)", MessageBoxButtons.OK);  
  93.             return false;  
  94.         }  
  95.  
  96.         return true;  
  97.     } 

問題1:無法一次性開辟足夠大空間(如1G),寫入大視頻時,會導(dǎo)致報內(nèi)存不足。

問題2:System.Convert.ToInt32()會使3G的視頻時,會報類型轉(zhuǎn)換失敗,數(shù)值值過大。

上面兩個問題在網(wǎng)絡(luò)中所有的方法中都普遍存在的,都會導(dǎo)致無法導(dǎo)入700M以上的視頻數(shù)據(jù)。

OLEDB方法對ORCLE 8以后的大字段操作不在支持,我在解決問題的過程中轉(zhuǎn)向了OracleClient命名空間下的方法來操作BLOB大字段,主要參考微軟官方http://msdn.microsoft.com/zh-cn/library/cydxhzhz(v=VS.90).aspx和博客園中的http://www.cnblogs.com/zhengmaoch/archive/2005/08/10/212014.html。這兩份資料對我解決500M以下數(shù)據(jù)量的視頻很有幫助,但是1G甚至是3G以上視頻數(shù)據(jù)是無法解決的。上面兩處使用了事務(wù)處理在導(dǎo)500M以上數(shù)據(jù)時,會報“ORA-22297: warning: Open LOBs exist at transaction commit time ”錯誤,主要因為提交事務(wù)時數(shù)據(jù)文件沒有讀完。

經(jīng)過試驗和參考http://msdn.microsoft.com/en-us/library/system.io.filestream.read.aspx方法,終于完全解決上面兩個問題,實現(xiàn)大視頻量數(shù)據(jù)導(dǎo)入BLOB字段。

 
 
 
  1. ///   
  2. /// 2010.10.22  
  3. /// 讀取視頻數(shù)據(jù)進(jìn)入ORACLE大字段中  
  4. ///   
  5. ///   
  6. ///   
  7. ///   
  8. public bool OracleUpload(string fileToUpload, string uploadSQL)  
  9. {  
  10.     /*  
  11.      * Get Connected  
  12.      */ 
  13.     string connection = strConn;  
  14.     OracleConnection conn;  
  15.     conn = new OracleConnection(connection);  
  16.     conn.Open();  
  17.     OracleCommand cmd = new OracleCommand(uploadSQL, conn);  
  18.     OracleTransaction transaction = conn.BeginTransaction();  
  19.     cmd.Transaction = transaction;  
  20.     OracleDataReader reader = cmd.ExecuteReader();  
  21.     using (reader)  
  22.     {  
  23.         try 
  24.         {  
  25.             reader.Read();  
  26.             OracleLob tmpBlob = reader.GetOracleLob(4);  
  27.             reader.Close();  
  28.             FileStream fsBlob = new FileStream(fileToUpload, FileMode.OpenOrCreate, FileAccess.Read);  
  29.             //BinaryReader br = new BinaryReader(fs);  
  30.             tmpBlob.BeginBatch(OracleLobOpenMode.ReadWrite);  
  31.             long length = fsBlob.Length;  
  32.  
  33.             int numBytesToRead = System.Convert.ToInt32(length / 10);//解決問題2  
  34.             int numBytesRead = 0;  
  35.             int n;  
  36.             byte[] Buffer = new byte[numBytesToRead];  
  37.             //2010.10.25  修改加 將文件分為10塊 防止文件為3.3G以上  
  38.              //解決問題1  
  39.             for (int i = 0; i < 9; i++)   
  40.             {  
  41.                   
  42.                 n = 0;  
  43.                // numBytesToRead = length / 5;  
  44.                 Buffer = new byte[numBytesToRead];   
  45.                 numBytesRead = 0;  
  46.                 while ((n = fsBlob.Read(Buffer, numBytesRead, numBytesToRead)) > 0)  
  47.                 {  
  48.                     numBytesRead += n;  
  49.                     numBytesToRead -= n;  
  50.                 }  
  51.                 numBytesToRead = System.Convert.ToInt32(length / 10);  
  52.                 tmpBlob.Write(Buffer, 0, numBytesToRead);  
  53.             }  
  54.  
  55.  
  56.             numBytesToRead = System.Convert.ToInt32(length / 10+ length % 10);  
  57.             numBytesRead = 0;  
  58.             n = 0;  
  59.             int tmpLength = numBytesToRead;  
  60.             byte[] Buffer2 = new byte[tmpLength];  
  61.             while ((n = fsBlob.Read(Buffer2, numBytesRead, numBytesToRead)) > 0)  
  62.             {  
  63.                 numBytesRead += n;  
  64.                 numBytesToRead -= n;  
  65.             }  
  66.             //numBytesToRead = tmpLength;  
  67.             tmpBlob.Write(Buffer2, 0, tmpLength);  
  68.  
  69.             fsBlob.Close();  
  70.             tmpBlob.EndBatch();  
  71.             cmd.Parameters.Clear();  
  72.             Buffer = null;      
  73.         }  
  74.         catch(Exception ex)  
  75.         {  
  76.             MessageBox.Show("出錯:"+ex.Message);  
  77.             //關(guān)閉  
  78.             reader.Close();  
  79.             transaction.Commit();  
  80.             conn.Close();  
  81.             return false;  
  82.         }  
  83.     }  
  84.  
  85.     reader.Close();  
  86.     transaction.Commit();  
  87.     conn.Close();  
  88.     return true;  

上面的方法完全能處理4G以下的視頻數(shù)據(jù)的導(dǎo)入問題,已經(jīng)經(jīng)過驗證的。PLSQL Developer工具同樣無法讀取BLOB字段中的大數(shù)據(jù)量的視頻,如需讀取請詳細(xì)參照http://www.cnblogs.com/wuhenke/archive/2010/10/25/1860752.html

 
 
 
  1. ///   
  2. /// 從數(shù)據(jù)庫中讀出大字段到文件中  
  3. ///   
  4. ///   
  5. ///   
  6. public bool OracleRead(string uploadSQL)  
  7. {  
  8.     string connection = strConn;  
  9.     OracleConnection conn;  
  10.     conn = new OracleConnection(connection);  
  11.     conn.Open();  
  12.  
  13.  
  14.     OracleCommand cmd = new OracleCommand(uploadSQL, conn);  
  15.     long readStartByte = 0;//從BLOB數(shù)據(jù)體的何處開始讀取數(shù)據(jù)  
  16.     int hopeReadSize = 1024; //希望每次從BLOB數(shù)據(jù)體中讀取數(shù)據(jù)的大小  
  17.     long realReadSize = 0;//每次實際從BLOB數(shù)據(jù)體中讀取數(shù)據(jù)的大小  
  18.     //CommandBehavior.SequentialAccess將使OracleDataReader以流的方式加載BLOB數(shù)據(jù)  
  19.     string filename = "F:\\Test"+DateTime.Now.Day+DateTime.Now.Minute+DateTime.Now.Second+".avi";  
  20.     OracleDataReader dr = cmd.ExecuteReader(CommandBehavior.SequentialAccess);  
  21.     while (dr.Read())  
  22.     {  
  23.         FileStream fs = new FileStream(filename, FileMode.Create);  
  24.         byte[] buffer = new byte[hopeReadSize];  
  25.         realReadSize = dr.GetBytes(0, readStartByte, buffer, 0, hopeReadSize);  
  26.         //循環(huán),每次讀取1024byte大小,并將這些字節(jié)寫入流中  
  27.         while ((int)realReadSize == hopeReadSize)  
  28.         {  
  29.             fs.Write(buffer, 0, hopeReadSize);  
  30.             readStartByte += realReadSize;  
  31.             realReadSize = dr.GetBytes(0, readStartByte, buffer, 0, hopeReadSize);  
  32.         }  
  33.         //讀取BLOB數(shù)據(jù)體最后剩余的小于1024byte大小的數(shù)據(jù),并將這些字節(jié)寫入流中  
  34.         realReadSize = dr.GetBytes(0, readStartByte, buffer, 0, hopeReadSize);  
  35.         fs.Write(buffer, 0, (int)realReadSize);  
  36.     }             
  37.     //transaction.Commit();  
  38.     conn.Close();  
  39.         return true;  

網(wǎng)站欄目:Oracle中利用BLOB字段存儲4GB以下視頻數(shù)據(jù)
標(biāo)題來源:http://www.5511xx.com/article/cohchdo.html