1. 程式人生 > >mysql中二進位制形式儲存檔案資料

mysql中二進位制形式儲存檔案資料

檔案在資料庫中要搞清楚下面幾個內容:
1   mysql儲存大容量的二進位制檔案的格式是blob,其實除了圖片還可以存別的
2   要向資料庫儲存二進位制的檔案一定要把要儲存的資料轉換成二進位制流
廢話就不多說了,大家看看程式碼很容易明白,先來看一個app程式,當然首先您要在資料庫
中先建立一個用於儲存圖片的表和相應的列,資料格式為blob

package com.lizhe;
import java.io.*;
import java.sql.*;
public class PutImg {
 public void putimg() {
  try {
   Class.forName("org.gjt.mm.mysql.Driver").newInstance();
   String url = "jdbc:mysql://localhost/img?user=root&password=root&useUnicode=
true&characterEncoding=gbk";
   Connection conn = DriverManager.getConnection(url);
   Statement stmt = conn.createStatement();
   //stmt.execute("insert   into   imgt (id)   values   (5)");
   stmt.close();
   PreparedStatement pstmt = null;
   String sql = "";
   File file = new File("c:\\blog.jpg");
   InputStream photoStream = new FileInputStream(file);
   //sql = "   UPDATE   imgt   SET   img   =   ?   ";
     
   sql = "INSERT INTO imgtable  (img) VALUES (?)";
   
   pstmt = conn.prepareStatement(sql);
   pstmt.setBinaryStream(1, photoStream, (int) file.length());
   pstmt.executeUpdate();
   pstmt.close();
   conn.close();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 public static void main(String args[]){
  PutImg pi=new PutImg();
  pi.putimg();
 }
}
 


InputStream photoStream = new FileInputStream(file);
可以很清楚的看到我們首先把一個圖片檔案(當然也可以是別的什麼檔案)轉換成了一個二進位制輸入流
pstmt.setBinaryStream(1, photoStream, (int) file.length());
這個方法建議大家去查一下API文件,第一個引數是萬用字元位置沒的說,第二個引數是流,這和以
往的string型別的引數不太一樣,我剛看到的時候也覺得豁然開朗了,但是到這裡還沒完,不同於
以往的字串引數,這裡我們還需要第三個引數來設定這個流的長度,這裡也就是這個檔案的長
度,匯出資料庫中的sql,一切都清楚了
INSERT INTO `m_diy` VALUES (2,?\0 JFIF\0   \0H\0H\0\0?? Exif\0\0MM\0*\0\0\0 \0
 \0 \0\0\0 \0 \0\0  \0 \0\0\0 \0\0\0b  \0 \0\0\0 \0\0\0j (\0 \0\0\0 \0 \0\0 1\0 \
0\0\0 \0\0\0r 2\0 \0\0\0 \0\0\0?i\0 \0\0\0 \0\0\0\0\0\0\0\0\0H\0\0\0 \0\0\0H\0\0\0
 Adobe Photoshop CS Windows\02007:03:18 23:08:15\0\0\0\0\0 ?\0 \0\0\0 ??\0\0?\0 \0
\0\0 \0\0\0? \0 ........等等
其實就是將檔案先轉換成了二進位制的流,然後插入到了sql語言中,向資料庫寫入了很長很長的一
段sql語句

 
 
然後我們再來寫一個app程式將這個檔案讀出來,儲存成一個圖片檔案

package com.lizhe;
import java.io.*;
import java.sql.*;
class GetImg {
 
 private static final String URL = "jdbc:mysql://localhost/img?user=root&password=ro
ot&useUnicode=true&characterEncoding=gbk";
 private Connection conn = null; 
 private PreparedStatement pstmt = null; 
 private ResultSet rs = null; 
 private File file = null; 

 public void blobRead(String outfile, int picID) throws Exception {
  FileOutputStream fos = null;
  InputStream is = null;
  byte[] Buffer = new byte[4096];
  try {
   Class.forName("org.gjt.mm.mysql.Driver").newInstance();
   conn = DriverManager.getConnection(URL);
   pstmt = conn.prepareStatement("select img from imgt where id=?");
   pstmt.setInt(1, picID); // 傳入要取的圖片的ID
   rs = pstmt.executeQuery();
   rs.next();
   file = new File(outfile);
   if (!file.exists()) {
    file.createNewFile(); // 如果檔案不存在,則建立
   }
   fos = new FileOutputStream(file);
   is = rs.getBinaryStream("img");
   int size = 0;
   
   while ((size = is.read(Buffer)) != -1) {
    // System.out.println(size);
    fos.write(Buffer, 0, size);
   }
  } catch (Exception e) {
   System.out.println( e.getMessage());
  } finally {
   // 關閉用到的資源
   fos.close();
   rs.close();
   pstmt.close();
   conn.close();
  }
 }
 public static void main(String[] args) {
  try {
   GetImg gi=new GetImg();
   gi.blobRead("c:/getimgs/1.jpg", 5);
  } catch (Exception e) {
   System.out.println("[Main func error: ]" + e.getMessage());
  }
 }
}


這裡需要注意的是
 is = rs.getBinaryStream("img");
img是資料庫中相應的列名,其實和rs.getString()方法差不多,只不過這個方法是讀取二進位制流的
最後在帖兩個bs系統上用的檔案給大家參考

通過struts的action向資料庫寫入二進位制圖片

/*
 * Generated by MyEclipse Struts
 * Template path: templates/java/JavaClass.vtl
 */
package com.lizhe.struts.action;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.Statement;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.upload.FormFile;
import com.lizhe.struts.form.UpimgForm;
/** 
 * MyEclipse Struts
 * Creation date: 05-18-2007
 * 
 * XDoclet definition:
 * @struts.action path="/upimg" name="upimgForm" input="/userhomepage.jsp"
 * @struts.action-forward name="userhome" path="/userhomepage.jsp" redirect="true" 
contextRelative="true"
 */
public class UpimgAction extends Action {
 /*
  * Generated Methods
  */
 /** 
  * Method execute
  * @param mapping
  * @param form
  * @param request
  * @param response
  * @return ActionForward
  * @throws IOException 
  * @throws FileNotFoundException 
  */
 public ActionForward execute(ActionMapping mapping, ActionForm form,
   HttpServletRequest request, HttpServletResponse response) throws FileNotFoundE
xception, IOException {
  UpimgForm upimgForm = (UpimgForm) form;// TODO Auto-generated method stub
  
  FormFile file=upimgForm.getFile();
  InputStream is=file.getInputStream();
  
  try {
   Class.forName("org.gjt.mm.mysql.Driver").newInstance();
   String url = "jdbc:mysql://localhost/blog?user=root&password=root&useUnicode=t
rue&characterEncoding=gb2312";
   Connection conn = DriverManager.getConnection(url);
   Statement stmt = conn.createStatement();
   //stmt.execute("insert   into   img (id)   values   (5)");
   stmt.close();
   PreparedStatement pstmt = null;
   String sql = "";
   //File file = new File("c:\\blog.jpg");
   //InputStream photoStream = new FileInputStream(file);
   //sql = "   UPDATE   imgt   SET   img   =   ?   ";
     
   sql = "INSERT INTO img (img) VALUES (?)";
   
   pstmt = conn.prepareStatement(sql);
   pstmt.setBinaryStream(1, is, (int) file.getFileSize());
   pstmt.executeUpdate();
   pstmt.close();
   conn.close();
  } catch (Exception e) {
   e.printStackTrace();
  }
  
  return mapping.findForward("userhomepage");
 }
}

和app的方式幾乎是一樣的
第二個檔案是通過jsp將資料庫中的圖片顯示在頁面上
這個有些不同
     

其中在oracle資料庫中也可以如此使用,確保資料的安全哦!可以不用儲存路徑的方法

相關推薦

mysql二進位制形式儲存檔案資料

檔案在資料庫中要搞清楚下面幾個內容: 1   mysql儲存大容量的二進位制檔案的格式是blob,其實除了圖片還可以存別的 2   要向資料庫儲存二進位制的檔案一定要把要儲存的資料轉換成二進位制流 廢話就不多說了,大家看看程式碼很容易明白,先來看一個app程式,當然首先您要

c語言 將記憶體資料二進位制形式寫入檔案 檔案資料表現形式

最近有在寫關於將記憶體中的資料寫入檔案的程式,當程式執行後,卻發現檔案中的位元組資料有些難以理解。思考後發現了其中的道理。 程式碼如下: #include<stdio.h> #include<stdlib.h> struct BlockInfo { bool is

計算機數值型資料二進位制形式儲存過程的原碼,反碼與補碼

在計算機系統中,數值一律用補碼來表示和儲存。原因在於,使用補碼,可以將符號位和數值域統一處理;同時,加法和減法也可以統一處理。此外,補碼與原碼相互轉換,其運算過程是相同的,不需要額外的硬體電路。

smartupload實現 jsp頁面上傳檔案檔案二進位制形式儲存在資料庫

<%@page import="com.sys.utils.DBConnection"%> <%@ page language="java" import="java.sql.*,com.jspsmart.upload.*"%> <jsp:us

探討-資訊管理系統,影象、檔案資料儲存方式

      常用的資訊管理系統,經常會有大量的法規、影象、附件等檔案需要存放,與之相對的許多大型資料庫系統也有對應的資料庫型別用於存放,然而,在一些大型應用管理系統中,常常會因為這些資料型別的存在或者資料庫設計的不合理,導致系統非常慢、所需的儲存空間非常大等一系列讓設計、開發

fwrite和fread函式的用法小結(怎麼樣以二進位制形式儲存和讀取檔案

返回值:讀或寫的記錄數,成功時返回的記錄數等於nmemb,出錯或讀到檔案末尾時返回的記錄 數小於nmemb,也可能返回0。     fread和fwrite用於讀寫記錄,這裡的記錄是指一串固定長度的位元組,比如一個int、一個結構體或者一個定長陣列。引數size指出一條記錄的長度,而nmemb指出要讀或寫多

詳解如何通過Mysql二進位制日誌恢復資料庫資料

經常有網站管理員因為各種原因和操作,導致網站資料誤刪,而且又沒有做網站備份,結果不知所措,甚至給網站運營和盈利帶來負面影響。所以本文我們將和大家一起分享學習下如何通過Mysql的二機制日誌(binlog)來恢復資料。 系統環境: 作業系統:CentOS 6.5 X64  (虛擬機器

二進位制形式操作檔案rb、wb、ab

操作檔案預設的是text文字,除了文字之外還有圖片、視訊等格式的檔案。另外,使用二進位制操作檔案可以跨平臺。 rb # 二進位制讀檔案不需要指定編碼方式 f = open('data', 'rb') res = f.read() f.close() print(res) # b'\x

圖片轉化成二進位制儲存檔案。再轉化為圖片

package com.company; import java.awt.image.BufferedImage; import java.io.*; import javax.imageio.ImageIO; import sun.misc.BASE64Decoder; import sun

用source命令往mysql匯入sql大檔案

用source命令往mysql中匯入sql大檔案 (我用的是MariaDB,安裝比mysql簡單) 比較好的辦法仍是用mysql的source命令: 1、開啟命令列,到mysql的bin目錄  C:\Program Files\MariaDB 10.3\bin\&nbs

mysql四種儲存引擎的區別和選擇

前言 資料庫儲存引擎是資料庫底層軟體組織,資料庫管理系統(DBMS)使用資料引擎進行建立、查詢、更新和刪除資料。不同的儲存引擎提供不同的儲存機制、索引技巧、鎖定水平等功能,使用不同的儲存引擎,還可以 獲得特定的功能。現在許多不同的資料庫管理系統都支援多種不同的資料引擎。MySQL的核心就是儲存引擎。 儲存引

如何通過 MySQL二進位制日誌恢復資料庫資料

經常有網站管理員因為各種原因和操作,導致網站資料誤刪,而且又沒有做網站備份,結果不知所措,甚至給網站運營和盈利帶來負面影響。所以本文我們將和大家一起分享學習下如何通過 MySQL 的二機制日誌(binlog)來恢復資料。 系統環境 作業系統:CentOS 6.5 X64 (虛擬機器); Web 服務:PHP

mysql的增刪改以及資料備份(講義)

----分組查詢&篩選學習: --關鍵字:group by 分組欄位名,分組欄位名.... --注意1:使用了分組後,在select語句中只允許出現分組欄位和多行函式。 --注意2:如果是多欄位分組,則先按照第一欄位分組,

MySql把一個表的資料插入到另一個表

將一個表的資料插入到另外一個表中的幾種情況如下: 1.如果2張表的欄位一致,並且希望插入全部資料,可以用這種方法:      INSERT INTO 目標表 SELECT * FROM 來源表;      例如:insert into insertTest sele

計算機二進位制儲存方法

1個位元組它不管怎麼樣還是隻能表示256個數,因為有符號所以我們就把它表示成範圍:-128-127。它在計算機中是怎麼儲存的呢?可以這樣理解,用最高位表示符號位,如果是0表示正數,如果是1表示負數,剩下的7位用來儲存數的絕對值的話,能表示27個數的絕對值,再考慮正負兩種情況

MySQL如何按月統計資料

表finance有倆個欄位如下 date date money double(15,2) 下面需要對錶 finance的2010年財務資料,按月進行統計 Sql程式碼 select DATE_FORMAT(date,'%Y-%m') as month,sum(money)

4 Springboot使用redis儲存集合資料,並模擬條件查詢、分頁讀取

前面幾篇講了使用redis儲存單個物件,自動快取、更新、刪除的做法,在實際專案中,更常用的是分頁查詢集合資料,條件查詢(譬如按照新增時間倒序排列)。 redis本身是不提供條件查詢的,因為是一個非關係型資料庫,那麼其實通過一些手段,也是能完成條件查詢的,尤其是有順序的條件查

MySQL 你應該使用什麼資料型別表示時間?

導讀 當你需要儲存日期時間資料時,一個問題來了:你應該使用 MySQL 中的什麼型別?使用 MySQL 原生的 DATE 型別還是使用 INT 欄位把日期和時間儲存為一個純數字呢? 在這篇文章中,我將解釋 MySQL 原生的方案,並給出一個最常用資料型別的對比表。我們也

mysql建立唯一約束防止資料重複

針對資料重複插入的情況,我們通常會在業務程式碼中進行處理,就是說入庫的時候先查一遍有沒有,沒有記錄的情況再准許入庫。但是如果只是自己處理業務程式碼時先查後入庫,併發高時會發生意想不到的後果。 比如現在表tab裡有兩個欄位fa, fb。業務規定,fa和fb的值只

python往mysql插入datetime型別的資料

這幾天幾天剛剛學習python,就動手練習了一下,主要是關於mysql資料庫方向的。      我們都知道python的%萬用字元有:%d(整型),%s(字元型),%f(浮點型)。那麼關於時間dat