① 我想創建一個資料庫用來存儲圖片 在SQL 2005中我創了一個表,create table a( int id smallint primary k
image 是圖片格式的
而你的C:\Users\angle\Pictures\Pictures\2.jpg是個圖片路徑
存儲圖片的時候 一般只存儲圖片路徑 就可以 這樣資料庫就比較輕便
你的方式是存儲圖片的二進制流 存的話資料庫會很大
② 如何在sql server中存儲圖片
1、首先可以存儲圖片鏈接,設置圖片鏈接欄位,如下圖所示。
③ 如何在資料庫中同時保存文本和圖片
向資料庫中保存不同類型的文件,和在資料庫中保存圖片是一樣的。就是向資料庫以byte形式存入
向資料庫中保存不同類型的文件,和在資料庫中保存圖片是一樣的。就是向資料庫以byte形式存入
然後就是寫入資料庫,代碼如下:
FileInfo fi = new FileInfo( txtFileName.Text );// Replace with your file name
if ( fi.Exists
{
byte[] bData = null;
int nNewFileID = 0;
// Read file data into buffer
using ( FileStream fs = fi.OpenRead() )
{
bData = new byte[fi.Length];
int nReadLength = fs.Read( bData,0, (int)(fi.Length) );
}
// Add file info into DB
string strQuery = "INSERT INTO FileInfo "
+ " ( FileName, FullName, FileData ) "
+ " VALUES "
+ " ( @FileName, @FullName, @FileData ) "
+ " SELECT @@IDENTITY AS 'Identity'";
SqlCommand sqlComm = new SqlCommand( strQuery, sqlConn );
sqlComm.Parameters.Add( "@FileName", fi.Name );
sqlComm.Parameters.Add( "@FullName", fi.FullName );
sqlComm.Parameters.Add( "@FileData", bData );
// Get new file ID
SqlDataReader sqlReader = sqlComm.ExecuteReader();
if( sqlReader.Read() )
{
nNewFileID = int.Parse(sqlReader.GetValue(0).ToString());
}
sqlReader.Close();
sqlComm.Dispose();
if( nNewFileID > 0 )
{
// Add new item in list view
ListViewItem itmNew = lsvFileInfo.Items.Add( fi.Name );
itmNew.Tag = nNewFileID;
}
}
4.而讀出的代碼如下:
// Get new file name
stringstrFullName =
dlgFBSave.SelectedPath;
if( strFullName[strFullName.Length - 1] != '//'
)
strFullName
+= @"/";
strFullName +=
lsvFileInfo.SelectedItems[0].Text;
stringstrQuery = "SELECT FileData FROM FileInfo
"
+
" WHERE FileID = " + lsvFileInfo.SelectedItems[0].Tag.ToString();
SqlDataAdapter
sqlDAdapter =newSqlDataAdapter(strQuery,sqlConn);
DataSet
sqlRecordSet =newDataSet();
byte[] bData =null;
//Get file data from DB
try
{
sqlDAdapter.Fill(
sqlRecordSet, "FileInfo" );
foreach( DataRow drinsqlRecordSet.Tables["FileInfo"].Rows)
{
if( dr["FileData"] != DBNull.Value )
bData
= (byte[] )dr["FileData"];
}
}
catch(SqlException sqlErr)
{
MessageBox.Show(
sqlErr.Message );
}
catch
{
MessageBox.Show(
"Failed to read data from DB!" );
}
sqlRecordSet.Dispose();
sqlDAdapter.Dispose();
if( bData !=null)
{
// Save file
FileInfo
fi =newFileInfo( strFullName
);
if( !fi.Exists )
{
//Create the file.
using(FileStream fs = fi.Create())
{
fs.Write(
bData, 0, bData.Length);
}
}
else
{
//Create the file.
using(FileStream fs =
fi.OpenWrite())
{
fs.Write(
bData, 0, bData.Length);
}
}
}
④ for循環一個int數組,如何把List<String>里的每一個圖片地址添加到對應的Int數組裡面
不是很明白你的意思,如果純粹想用數字代替img是不可能的,不是一種數據類型,如果只是為了做索引排序的話可以考慮可以考慮使用map<int, String>啊,不知道你是什麼語言,
C++可以使用map<int, String> kv
kv.insert(pair<int, String>(1,mimg.position(0)));
kv.insert(pair<int, String>(2,mimg.position(1)));
kv.insert(pair<int, String>(3,mimg.position(2)));
... ...
kv.insert(pair<int, String>(9,mimg.position(8)));
使用的時候就是
String str = kv.find(1)->second
str =kv.find(2)->second
... ...
2.C#可以是Dictionary<int, String> kv
kv.Add(1, mimg.position(0));
kv.Add(2,mimg.position(1));
kv.Add(3mimg.position(2));
... ...
kv.Add(9,mimg.position(8));
使用的時候就是
String str = kv[1] ;
str =kv[2] ;
... ...
3.Java可以是HashMap<int, String> kv
kv.put(1,mimg.position(0));
kv.put(2,mimg.position(1));
kv.put(3mimg.position(2));
... ...
kv.put(9,mimg.position(8));
使用的時候就是
String str = kv.get(1) ;
str =kv.get(2);
... ...
4.C語言就比較復雜了,需要結構體,還要寫插入獲取方法,當然,也可以取巧。
char* indexs[0];
int count;
memset(indexs, 0, sizeof(indexs));
for(count = 0; count < 9; count++)
{
indexs[count ] = xxx xxx;
}
然後使用的時候 char* str = indexs[1]; 這種方法索引也是從0開始,但與list的差別是list排序是按它的方法,這個可以按照自己的意思重新排,比如indexs[0]可以對應list中第3個圖片路徑。
⑤ 有n個int數據,保存在內存中,可能會如何存儲繪制一個示意圖
有n個int數據,如果是以數組的形式申明的,則它們保存在內存中,是以「鄰居」的形式存儲的。
比如說,int arr[100];
則它們在內存中,是以連續100個int單元的形式存儲的。首先是arr[0],然後它的下一個是arr[1],然後是arr[2],……,最後是arr[99]。
⑥ C#ACCESS做後台,如何存放圖片
首先將圖片轉為大字元穿string64
方法:1存儲--------------------
//為了選圖片方便我用了個控制項..你應該知道這是什麼
OpenFileDialogof=newOpenFileDialog();
if(of.ShowDialog()==DialogResult.OK)
{
//獲取圖片路徑
Filepatch=of.FileName.ToString();
//圖片名稱
Filekname=Path.GetExtension(Filepatch).Substring(1,3);
intKslength=Filepatch.LastIndexOf("\")+1;
ImageName=Filepatch.Substring(Kslength);
}
Imageim=Image.FromFile(Filepatch);
//內存流
MemoryStreamms=newMemoryStream();
//保存流
im.Save(ms,getimagetype(Filekname));
byte[]by=ms.GetBuffer();
UTF8=by;
//轉換為string類型了
stringutf8zj=Convert.ToBase64String(by);
//這步是我給他寫到了文件裡面.你可以直接寫到資料庫中
StreamWritersw=newStreamWriter("d://測試流.txt",false,System.Text.Encoding.UTF8,128);
sw.WriteLine(utf8zj);
sw.Close();
MessageBox.Show("成功保存!--d://測試流.txt");
方法2讀取--------------------
stringutf8zj;
//我這個是在文件里讀取,你應該在資料庫,那裡我就不寫了是你的程序..
StreamReadersr=newStreamReader("d://測試流.txt",System.Text.Encoding.UTF8,true,128);
//讀取字元串流
utf8zj=sr.ReadToEnd();
//載入到內存
MemoryStreamms=newMemoryStream(Convert.FromBase64String(utf8zj));
//顯示
this.pictureBox1.Image=newBitmap(ms);
Bitmapb=newBitmap(ms);
stringpach=Application.StartupPath+@"img"+ImageName+"";
b.Save(pach);
sr.Close();
以上都很簡單的。如果你不明白加我QQ51606768我給你一個我有個小例子
⑦ 怎樣把圖片存入SQL資料庫表中
一、先來熟悉一下將要使用的對象方法:
用來獲取上一個頁面傳 遞過來的數據一般是使用Request對象。同樣的,我們也可以使用Request對象 來獲取上傳上來的文件數據,使用的方法是Request.BinaryRead()。
要從資料庫中讀出來圖片的數據顯示到網頁上面要用到的方法是:Request.BinaryWrite()。
二、在得到了圖片的數據,要保存到資料庫中的時候,不可以直接使用Insert語句對資料庫進行操作,而是要使用ADO的AppendChunk方法。
同樣的,讀出資料庫中的圖片數據,要使用GetChunk方法。
各個方法的具體語法如下:
*Request.BinaryRead語法:
variant=Request.BinaryRead(count)
參數
variant
返回值保存著從客戶端讀取到數據。
count
指明要從客戶端讀取的數據量大小,這個值小於或者等於使用方法
Request.TotalBytes得到的數據量。
*Request.BinaryWrite語法:
Request.BinaryWritedata
參數
data
要寫入到客戶端瀏覽器中的數據包。
*Request.TotalBytes語法:
variant=Request.TotalBytes
參數
variant
返回從客戶端讀取到數據量的位元組數。
*AppendChunk語法
將數據追加到大型文本、二進制數據Field或Parameter對象。
object.AppendChunkData
參數
objectField或Parameter對象
Data變體型,包含追加到對象中的數據。
說明
使用Field或Parameter對象的AppendChunk方法可將長二進制或字元數
據填寫到對象中。在系統內存有限的情況下,可以使用AppendChunk方法對長
整型值進行部分而非全部的操作。
*GetChunk語法
返回大型文本或二進制數據Field對象的全部或部分內容。
variable=field.GetChunk(Size)
返回值
返回變體型。
參數
Size長整型表達式,等於所要檢索的位元組或字元數。
說明
使用Field對象的GetChunk方法檢索其部分或全部長二進制或字元數據。
在系統內存有限的情況下,可使用GetChunk方法處理部分而非全部的長整型
值。
GetChunk調用返回的數據將賦給「變數」。如果Size大於剩餘的數據,則
GetChunk僅返回剩餘的數據而無需用空白填充「變數」。如果欄位為空,則
GetChunk方法返回Null。
每個後續的GetChunk調用將檢索從前一次GetChunk調用停止處開始的數
據。但是,如果從一個欄位檢索數據然後在當前記錄中設置或讀取另一個欄位
的值,ADO將認為已從第一個欄位中檢索出數據。如果在第一個欄位上再次調
用GetChunk方法,ADO將把調用解釋為新的GetChunk操作並從記錄的起始
處開始讀取。如果其他Recordset對象不是首個Recordset對象的副本,則
訪問其中的欄位不會破壞GetChunk操作。
如果Field對象的Attributes屬性中的adFldLong位設置為True,則可
以對該欄位使用GetChunk方法。
如果在Field對象上使用Getchunk方法時沒有當前記錄,將產生錯誤3021
(無當前記錄)。
三、設計資料庫,作為測試的資料庫結構如下(Access97):
欄位名稱類型描述
id自動編號主鍵值
imgOLE對象用來保存圖片數據
對於在MSSQLServer7中,對應的結構如下:
欄位名稱類型描述
idint(Identity)主鍵值
imgimage用來保存圖片數據
四、正式編寫純ASP代碼上傳部分了,首先,有一個提供給用戶的上傳界面,可以讓用戶選擇要上傳的圖片。代碼如下(upload.htm):
<html>
<body>
<center>
<formname="mainForm"enctype="multipart/form-data"
action="process.asp"method=post>
<inputtype=filename=mefile><br>
<inputtype=submitname=okvalue="OK">
</form>
</center>
</body>
</html>
注意代碼中黑色斜體的部分,一定要在Form中有這個屬性,否則,將無
法得到上傳上來的數據。
五、接下來,要在process.asp中對從瀏覽器中獲取的數據進行必要的處理,因為在process.asp中獲取到的數據不僅僅包含了想要的上傳上來的圖片的數據,也包含了其他的無用的信息,需要剔除冗餘數據,並將處理過的圖片數據保存到資料庫中,這里以Access97為例。具體代碼如下(process.asp):
<%
response.buffer=true
formsize=request.totalbytes
formdata=request.binaryread(formsize)
bncrlf=chrB(13)&chrB(10)
divider=leftB(formdata,clng(instrb(formdata,bncrlf))-1)
datastart=instrb(formdata,bncrlf&bncrlf)+4
dataend=instrb(datastart+1,formdata,divider)-datastart
mydata=midb(formdata,datastart,dataend)setconnGraph=server.CreateObject("ADODB.connection")
connGraph.ConnectionString="driver={MicrosoftAccessDriver(*.mdb)};DBQ="&
server.MapPath("images.mdb")&";uid=;PWD=;"
connGraph.Opensetrec=server.createobject("ADODB.recordset")
rec.Open"SELECT*FROM[images]whereidisnull",connGraph,1,3
rec.addnew
rec("img").appendchunkmydata
rec.update
rec.close
setrec=nothing
setconnGraph=nothing
%>
六、這樣就把上傳來的圖片保存到了名為images.mdb的資料庫中了,剩下的工作就是要將資料庫中的圖片數據顯示到網頁上面了。
一般在HTML中,顯示圖片都是使用<IMG>標簽,也就是<IMGSRC="圖片路徑">,但是圖片是保存到了資料庫中,「圖片路徑」是什麼呢?呵呵,其實這個SRC屬性除了指定路徑外,也可以這樣使用哦:
<IMGSRC="showimg.asp?id=xxx">
所以,要做的就是在showimg.asp中從資料庫中讀出來符合條件的數據,並返回到SRC屬性中就可以了,具體代碼如下(showimg.asp):
<%
setconnGraph=server.CreateObject("ADODB.connection")
connGraph.ConnectionString="driver={MicrosoftAccessDriver(*.mdb)};DBQ="&
server.MapPath("images.mdb")&";uid=;PWD=;"
connGraph.Open
setrec=server.createobject("ADODB.recordset")
strsql="selectimgfromimageswhereid="&trim(request("id"))
rec.openstrsql,connGraph,1,1
Response.ContentType="image/*"
Response.BinaryWriterec("img").getChunk(7500000)
rec.close
setrec=nothing
setconnGraph=nothing
%>
七、注意在輸出到瀏覽器之前一定要指Response.ContentType="image/*",以便正常顯示圖片。最後要注意的地方是,我的process.asp中作的處理沒有考慮到第一頁(upload.htm)中還有其他數據,比如<INPUTtype=tesxtname=userid>等等,如果有這些項目,process.asp就要注意處理掉不必要的數據。
⑧ 探求Oracle資料庫怎樣存儲圖片
商品圖片,用戶上傳的頭像,其他方面的圖片。目前業界存儲圖片有兩種做法:
1、 把圖片直接以二進制形式存儲在資料庫中
一般資料庫提供一個二進制欄位來存儲二進制數據。比如MySQL中有個blob欄位。Oracle資料庫中是blob或bfile類型
2、 圖片存儲在磁碟上,資料庫欄位中保存的是圖片的路徑。
一、圖片以二進制形式直接存儲在資料庫中
第一種存儲實現(PHP語言):
大體思路:
1、將讀取到的圖片用php程序轉化成二進制形式。再結合insert into 語句插入數據表中的blob類型欄位中去。
3、 從資料庫取出圖片展示的時候。則是直接發送圖片內容
4、
$row=mysql_fetch_object($result);
Header( "Content-type: image/gif");
echo $row->this_image;
實現代碼如下:
$PicturePath = 『/tmp/xxxjgjgj.jpg』;//假設這是上傳的圖片,php放在一個臨時文件夾。腳本執行完畢後自動刪除了。
$imgStream = fread(fopen($PicturePath, "r");
$blob_img = fread(fopen($imgStream, "r"), filesize($PicturePath));
$sql =」 INSERT INTO Images (this_image) VALUES ($blob_img)";
註:this_image就是數據表中一個blob欄位類型的欄位
================取出展示圖片代碼
$result=mysql_query("SELECT * FROM Images WHERE PicNum=$PicNum") or die("Cant perform Query");
$row=mysql_fetch_object($result);
Header( "Content-type: image/gif");
echo $row-> this_image;
總結:處理代碼感覺還真比較麻煩。其實,我從來沒用過在資料庫中以二進制存儲圖片的做法。我們用得更多的是存儲圖片的路徑,實際圖片是在磁碟上保存的(圖片二進制放到資料庫,把資料庫的負擔弄重了)。
據我了解,互聯網環境中,大訪問量,資料庫速度和性能方面很重要。一般在資料庫存儲圖片的做法比較少,更多的是將圖片路徑存儲在資料庫中,展示圖片的時候只需要連接磁碟路徑把圖片載入進來即可。因為圖片是屬於大欄位。一張圖片可能1m到幾m。
有個原則:圖片盡量不要存儲在資料庫中(是指不要二進制形式保存到欄位,而只保存圖片的路徑)。這樣的大欄位數據會加重資料庫的負擔,拖慢資料庫。在大並發訪問的情況下很重要。這是一個經驗。去看看dba對資料庫性能調優方面的分析都能得到這個答案的:就是圖片不要存儲在資料庫中。
就像這個規則一樣:文章分為標題、作者、添加時間、更新時間、文章內容、文章關鍵字
文章內容一般是比較長的。經常使用text欄位去存儲。文章的內容就屬於大欄位。一般文章內容可以拆分到單獨一個表中去。不要與文章信息存儲在一張表裡面。
我理解的原理是:mysql中一張表的數據是全部在一個數據文件中的。如果大欄位的數據也存儲在裡面。程序展示列表,比如文章列表。這個時候根本不需要展示文章內容的。但是仍然會影響速度,資料庫查找數據其實就是掃描那個數據文件,文件容量越小,速度就會越快(為什麼單表的容量在1g-2g的時候基本上要分表了)。拆分出去到一張單獨的表,就是單獨的文件了。我覺得,舉一反三,相互獨立,分離的思想不僅在系統開發中用到,在現實生活中經常存在的。相互混合,就會造成相互影響。小巧,簡潔是一種思想。
可以看看這篇翻譯的文章,
http//developer.51cto.com/art/201211/364472.htm
作者建議,三種東西永遠不要放到資料庫里,圖片,文件,二進制數據。作者的理由是,
對資料庫的讀/寫的速度永遠都趕不上文件系統處理的速度
資料庫備份變的巨大,越來越耗時間
對文件的訪問需要穿越你的應用層和資料庫層
把圖片縮略圖存到資料庫里?很好,那你就不能使用nginx或其它類型的輕量級伺服器來處理它們了。
給自己行個方便吧,在資料庫里只簡單的存放一個磁碟上你的文件的相對路徑,或者使用S3(備註:亞馬遜雲服務)或CDN之類的服務。
============================================================
關於mysql中的blob類型
bolb像int型那樣,分為blob、MEDIUMBLOB、LONGBLOB。其實就是從小到大,
blob 容量為64KB ,MEDIUMBLOB 容量為16M,LONGBLOB 容量為4G。
說實話,圖片用這樣子存儲用得還真少。使用php函數serialize進行序列化的值,我看到有人存入這個欄位中去。
php手冊:serialize返回字元串,此字元串包含了表示 value 的位元組流,可以存儲於任何地方。
mysql中blob欄位存儲圖片有個通信大小的設置:
圖片要傳輸給mysql存儲起來,那麼需要涉及到數據通信。mysql中有個配置是限制通信數據大小的。
my.conf配置文件中的max_allowed_packet,mysql默認的值是1M。
好多圖片尤其是原始圖可能不止1m。傳輸的數據(也就是圖片)超過這個設置大小。結果就會出錯
呵呵,限制挺多。感覺好麻煩。這樣子明顯佔用與mysql交互的通信時間嘛。延長響應時長了。我直接丟個圖片路徑」images/xxxx」給mysql。沒這么耗費資源。
其實所謂的性能,最關鍵是資料庫性能。因為隨著資料庫數據量增大,大部分時間耗費是在php,Java等語言等待資料庫返回數據的過程中耗費時間。
網站訪問量大了後,具體的語言不是瓶頸,瓶頸都在資料庫。用c,,php,java,net都能操作mysql資料庫獲取數據。語言之間可能存在速度執行差異,但是其實這種差別已經很小了。至少我覺得,給予用戶感覺不到明顯。執行相差0.0001秒用戶感覺並沒有明顯的區別。可能說,大並發(很多用戶同時訪問)的時候,就會體現到差別了。其實我覺得,大並發訪問是資料庫瓶頸。等待資料庫給予數據。沒達到一定級別實在體現不了差別。資料庫數據量達到一定級別。語言相差0.001s會給予用戶體驗上的差別。我想,這也是為什麼php很適合做web開發了。解析頁面速度快(解釋型語言,不需要編譯)。可以用java來與資料庫打交道獲取數據。php不直接操作資料庫,而是調用java提供的數據介面,獲取數據,馬上展示在頁面中。這是利用了php的頁面執行速度快的一個優勢。
備份圖片數據和遷移數據方便
圖片以二進制形式存儲在資料庫,有一個好處:備份的時候方便。直接備份資料庫,圖片也跟著備份。換句話說,遷移環境的時候是方便。
而圖片放在磁碟上的話,資料庫中存儲的只是圖片路徑。備份資料庫後。磁碟上的圖片也要跟著備份才行。
不過我覺得,備份這個好處不是很明顯。圖片在磁碟上,備份磁碟也沒很大的事情。打包壓縮也可以了。互聯網環境畢竟與傳統的軟體開發不同,web開發比較關注網站速度。也就是資料庫的速度。就像互聯網開發中,有時候為了速度,用空間換時間的做法比較普遍,所以往往在設計資料庫的時候並不一定遵循傳統資料庫設計三大範式。
資料庫中保存的是圖片路徑的話,在web開發環境下,其實有個更好處,就是cdn加速。就是下面要進行總結的地方。
二、資料庫中保存圖片路徑
一般是這樣子的:
按照年月日生成路徑。具體是按照年月日還是按照年月去生成路徑,根據自己需要(不一定是按照日期去生成)。
理解為什麼要分散到多個文件夾中去才是關鍵,涉及到一個原理就明白了:
操作系統對單個目錄的文件數量是有限制的。當文件數量很多的時候。從目錄中獲取文件的速度就會越來越慢。所以為了保持速度,才要按照固定規則去分散到多個目錄中去。
圖片分散到磁碟路徑中去。資料庫欄位中保存的是類似於這樣子的」images/2012/09/25/ 1343287394783.jpg」
原來上傳的圖片文件名稱會重新命名保存,比如按照時間戳來生成,1343287394783. jpg。這樣子是為了避免文件名重復,多個人往同一個目錄上傳圖片的時候會出現。
反正用什麼樣的規則命名圖片,只要做到圖片名稱的唯一性即可。
比如網站的並發訪問量大,目錄的生成分得月細越好。比如精確到小時,一個小時都可以是一個文件夾。同時0.001秒有兩個用戶同時在上傳圖片(因為那麼就會往同一個小時文件夾裡面存圖片)。因為時間戳是精確到秒的。為了做到圖片名稱唯一性而不至於覆蓋,生成可以在在時間戳後面繼續加毫秒微秒等。總結的規律是,並發訪問量越大。就越精確就好了。
我現在還沒碰到需要這么精細的。概率比較少。
有個方面總結一下:為什麼保存的磁碟路徑,是」images/2012/09/25/1343287394783.jpg」,而不是」 /images/2012/09/25/ 1343287394783.jpg」(最前面帶有斜杠)
我的理解:
連那個斜杠都不要。這里也是做到方便以後系統擴展。
在頁面中需要取出圖片路徑展示圖片的時候,如果是相對路徑,則可以使用」./」+」images/2012/09/25/1343287394783.jpg」進行組裝。
如果需要單獨的域名(比如做cdn加速的時候)域名,img1.xxx.com,img2.xxx.com這樣的域名,
直接組裝 「http//img1.xxx.com/」+」images/2012/09/25/1343287394783.jpg」
當然資料庫是可以在前面加斜杠/保存起來,/images/2012/09/25/ 1343287394783.jpg
其實不方便統一。比如相對路徑載入圖片的時候,則是」.」+」 /images/2012/09/25/ 1343287394783.jpg」
可能我還沒體會到壞處,以後會遇到問題的。不過,遵循慣例不加斜杠」 images/2012/09/25/ 1343287394783.jpg」就對了。
涉及到一個新問題:為什麼大部分系統都不會域名保存進去,像這樣子http//wwwxxx.com/images/2012/09/25/1343287394783.jpg保存到資料庫中
曾經與一個上海的網友聊天,他也是習慣不會把域名保存資料庫中過去。但當時我們兩聊的時候,他對」域名保存進去的做法」與」不保存域名進去」也沒有一個明確利弊。他就覺得,沒有什麼明顯的區別啊。
了解的知識越多,越有利於我們做決定。可能就是一個」感覺區別不是很大」的影響下,去做一個決定,反而對後面是比較大的影響的。至少是增加自己的工作量了。
其實把域名保存進去,也不是什麼滔天大罪的事情。但凡是經驗豐富的開發人員都不會這樣子做。這是一個經驗積累出來的,所以上海那個網友也對此並沒有明顯的概念很正常,他說他不知道cdn方面的(當然覺得存個域名進去沒什麼大不了的)。需要了解cdn知識,什麼情況下會用到cdn知識。
雖然是做開發人員,不需要關注運維和伺服器之類的知識。不過了解一些就有利於理解了。
這里涉及到cdn加速。
關於cdn原理(就是內容分發網路)
cdn,我理解其本質就是為了解決距離遠產生的速度問題,使用就近的服務。
從中國請求美國一台伺服器上的圖片。一般比較慢,因為距離這么遠,網路傳輸是存在損耗的,距離越遠,傳輸的時間就越長。一般會看到瀏覽器左下角顯示:「已響應,正在傳輸數據..」。這不是伺服器本身問題了。實際上伺服器早就響應請求,把數據發給客戶端,但是網路問題,就一直在傳輸,沒傳完了。
在中國,是南北距離遠的問題。南北還會涉及到跨網,南方用戶使用電信居多,北方用戶網通居多。兩個線路需要跨越,會有時間延遲。北京到廣州的距離,如果直接請求
cdn加速就是適應這個需求產生的:現在不請求美國的伺服器。直接在中國安放節點(節點是比較籠統的詞語,可以理解成一台伺服器,也可以理解成一個機房,就是一個點嘛),請求距離近的節點。這樣子就不需要那麼遠的距離了。
記得以前在長沙的網站,團購以城市分站的形式。北京和長沙用的是同一套程序。伺服器在長沙。北京用戶訪問北京站的時候,實際上需要遠距離訪問長沙的伺服器。速度怎麼都快不起來。跟伺服器性能完全沒關系。當時不懂這些。不清楚怎麼折騰。看那本《前端優化技巧》,想辦法去做js代碼壓縮,瀏覽器緩存之類的。實際上瞎折騰。不是說這些前端優化不重要,哲學上有主次矛盾之分,瓶頸在哪裡就去突破哪裡。沒解決主要矛盾,問題並不會迎刃而解。當時也不是資料庫瓶頸。如果去優化資料庫。也不會明顯改善。就那點數據量。根本就達不到瓶頸。哪裡談得上主要矛盾。隨著後來去其他公司工作,接觸一些東西,類似不找瓶頸的優化例子發生在身邊好幾次了,先沒找到瓶頸就瞎去優化。我的同事可能是抱著多多益善的心態去做的,但主要矛盾(技術上說是瓶頸)沒找到,也沒改善。
當時如果沒想到是距離問題。也就不會想到cdn,當時其實我根本不知道cdn服務。我只知道,google這些網站肯定在中國部署的伺服器,要不然,中國用戶還去訪問美國的伺服器,那再好的伺服器都會速度慢的。
由於自己搭建cdn環境和機房的資金比較大(需要大量的伺服器),也需要人力維護。反正一般的公司弄不起,其實根本不劃算。淘寶以前用商用的cdn服務,後來商用的扛不住了,就搭建了自己的cdn網。我不知道新浪有沒有自己搭建,但其實我覺得跟淘寶的特點有關,店鋪很多,無論是商品還是交易記錄總計起來商品很多的圖片,圖片都是靜態的部分,cdn本來就是用來做靜態的(圖片,css,js等)請求分發用的。
我之前在網上看到一句話,cdn網路不是一般的公司玩得起的。
一般的公司自己搭建cdn網路成本高,所以就有商業的cdn提供付費租用服務,這是一項很成熟的業務,很多這樣的公司,大部分全國性的互聯網公司都會使用到cdn。
總結:cdn服務。對於靜態內容是非常適合的。所以像商品圖片,隨著訪問量大了後,租用cdn服務,只需要把圖片上傳到他們的伺服器上去。
例子:北京訪問長沙伺服器,距離太遠。我完全可以把商品圖片,放到北京的雲服務(我覺得現在提供給網站使用的雲存儲其實就是cdn,給網站提供分流和就近訪問)上去。這樣子北京用戶訪問的時候,實際上圖片就是就近獲取。不需要很長距離的傳輸。
自己用一個域名img.xxxcom來載入圖片。這個域名解析到北京的雲服務上去。
做法:資料庫中保存的是」 images/2012/09/25/1343287394783.jpg」,
這些圖片實際上不存儲在web伺服器上。上傳到北京的cdn伺服器上去。
我從資料庫取出來,直接」img.xxxcom/」+」 images/2012/09/25/1343287394783.jpg」
比如如果還有多個,就命名img1.xxcom、img2.xxcom
反正可以隨便。所以如果把域名直接保存進去。就顯得很麻煩了。遷移麻煩。
像淘寶,凡客,亞馬遜這些電子商務網站,我們看到請求的時候,下面往往會有
img1.xxx.cdncom
img2.xxx.cdncom
其實他們保存在資料庫中的是相對路徑。有些是不需要在資料庫保存的,縮略圖可以實時訪問的時候用程序生成(節省很多存儲空間)
實際上,把域名保存在資料庫中,非常不利於系統遷移。一旦換個域名的話,原來保存在資料庫中的是「wwwabc.om/images/xxxxxx「,因為路徑都在資料庫中寫死了。下回換個域名就用不了了。那個時候自己去寫sql語句批量更新欄位吧。
幾個術語:
icp,Internet Content Provider,也就是網路內容提供者。聯想到我們運營一個網站需要icp備案了嗎?你自己運營網站,你就是icp服務商
IDC(Internet Data Center),互聯網數據中心。IDC的概念,目前還沒有一個統一的標准。通俗點,就是提供機房託管(伺服器租用和託管),域名注冊之類的。
關於淘寶的圖片存儲
了解到:淘寶以前使用了商用的存儲。但是沒法滿足需求。據說,到2010年,淘寶網後端保存著286億張圖片。商用的系統系統沒法滿足需求的時候。他們就自己開發了一個tfs。大規模的小文件在磁碟上讀取,需要磁碟磁頭頻繁的尋道和換道。大並發情況下和大量的操作確實很麻煩。其實借鑒了當時google公布的gfs設計論文。google有相冊服務。為每個用戶提供上傳圖片存儲。
估計,google是率先實現這種小文件網路存儲系統的。
有個觀點比較好:對於老闆們而言,往往覺得,用錢能解決的都不算問題。但問題在於,你遇到的問題,別人都沒遇到過。那這個時候你就沒有經驗可以參考或者直接拿來使用。只有自己參考一些思路去創造技術了。
三、關於圖片進行雲存儲(cdn加速)
曾經看過這個,這個是比較適合創業公司的。價格相對便宜
https//wwwupyun.com/
介紹提到,我們在全國各地部署了55個CDN節點,500多台伺服器,電信,聯通,移動和教育網的4線帶寬。
其實,現在的雲存儲本質就是一個cdn服務商。你把靜態的圖片上傳到他提供的伺服器上去(ftp方式上傳或者api形式編寫程序上傳)。他為你做就近節點訪問。
計費方式:按照流量付費,99元購買100g。怎麼算流量。每次訪問文件的大小累加,比如一個1m的文件,訪問一次流量就加1m。
我個人理解,對於圖片的量不大的情況下,使用這種雲服務,好處不是節省存儲空間。你自己的伺服器100g的空間可能創業型公司都沒用完,不是什麼存儲空間不夠用,然後去用雲存儲。以前我對cdn比較模糊,有這么點理解,或者以為是分散網站web伺服器流壓力,伺服器分流。這些好處是有的。但是,只要理解了cdn產生的背景和解決的關鍵問題後,就會明白雲存儲關鍵好處在於:給用戶就近節點訪問,加速。
我覺得,如果不是出於這個考慮,或者達不到這樣的目的。用其他方案也完全可以替代。何必使用雲存儲呢?就是你無非有實力做到全國多個節點去部署服務,才需要租用cdn來幫你,畢竟他們是規模產生的效益,專注於解決這個領域。
⑨ 用c語言如何讀取和保存jpg圖片文件
有這樣一個二進制文件,大小在100M左右,裡面存放了多張JPG圖片,文件格式如下:
無關數據區
JPG圖片數據區
無關數據區
JPG圖片數據區
無關數據區
JPG圖片數據區
......
已知JPG圖片起始標志為:「FF
D8
FF
E0
00
10
4A」,結束標志為:「FF
D9」。
現想把這些JPG圖片數據從該文件中讀出來,生成一個個單獨的圖片文件,該如何做呢?
幫你寫了個程序,
測試了只含有一個圖片信息的文件
int
len=0;
int
filesn=0;
void
ReadJpg(CFile
*sfp,const
char
*dstfile,unsigned
char
a,unsigned
char
b)
{
CFile
nf;
nf.Open(dstfile,CFile::modeCreate|CFile::modeWrite|CFile::typeBinary);
unsigned
t=0,t1=0;
nf.Write(&a,sizeof(char));
nf.Write(&b,sizeof(char));
while(1)
{
sfp->Read(&t,sizeof(char));
len++;
nf.Write(&t,sizeof(char));
if(t==0xFF)
{
sfp->Read(&t1,sizeof(char));
len++;
if(t1==0xD9)
break;
else
nf.Write(&t1,sizeof(char));
}
}
nf.Close();
}
調用:
void
test()
{
CFile
fp;
fp.Open("86b05621.jpg",CFile::modeRead|CFile::typeBinary);//文件名改一下
unsigned
char
a=0,b=0;
len=0;
while(1)
{
fp.Read(&a,sizeof(char));
len++;
if(len>=fp.GetLength())
break;
if(a==0xFF)
{
fp.Read(&b,sizeof(char));
len++;
if(b==0xD8)
{
filesn++;
char
filename[256];
sprintf(filename,"Jpg
%d.jpg",filesn);
ReadJpg(&fp,filename,a,b);
}
}
}
fp.Close();
}
思路是,先得到FF的值,然後再判斷下一位是否是0xD8,
但這里要說明一下,如果你的其它數據信息里也含有FF
D8值的話就會出錯了,
所以為保險起見,應該再多比較幾位,
JPG的頭是固定的,再往下就是EF
E0
00
1E,
建議樓主再往下比較四位比較保險(在程序中稍作修改即可)
你是不是在
分析某個
游戲的或程序的資源文件呀,如果是的話,這個資源文件應該配有一個
索引文件!或在其文件自身。索引可以列表索引,鏈表形示……
如果是你自已生成的文件包,最好加上索引,因為這樣可以提高效率!
⑩ 如何向ORACLE資料庫表中存入帶圖片的文件
create table test
(
NID VARCHAR2(1) not null,
IMG BLOB,
zhengqueFlag VARCHAR2(1),
cuowuFlag VARCHAR2(1)
)
說明:
1、IMG欄位只需要保存圖片,將圖片信息經過Base64編碼,存到資料庫BLOB欄位中。顯示的時候要經過Base64解碼。
2、對於像「正確」、「錯誤」用標志位在區別。你可以用1表示正確、0表示錯誤。當然你也可以用漢字的保存這樣的信息。自己來設計。
然後你到網上查一下怎麼樣對BLOB欄位進行操作。如果不行,我在增加回復。