導航:首頁 > 編程語言 > java序列化protobuf

java序列化protobuf

發布時間:2023-07-04 15:50:06

java 怎麼使用protobuf庫

1.到http://code.google.com/p/protobuf/downloads/list ,選擇其中的win版本下載,我選擇的是protoc-2.4.1-win32.zip
2.下載一個protobuf-java-2.4.1.jar文件(注意,要與你剛才下的proto.exe版本相同)
然後就開始開發了。
步驟:
1.用記事本編寫一個.proto文件:
}如:編寫的是test.proto

package protobuf;
option java_package = "com.sq.protobuf";
option java_outer_classname = "FirstProtobuf";
message testBuf {
required int32 ID = 1;
required string Url = 2;
}
將其放在與剛解壓的protoc.exe同級目錄中。
2.在cmd中,到protoc-2.4.1-win32文件夾下,
執行
E:\protoc-2.4.1-win32> protoc.exe --java_out=./ test.proto

則可以找到的一個生成的FirstProtobuf.java文件。

3.在MyEclipse中新建一個java project,建立包com.sq.protobuf,然後將剛才生成的FirstProtobuf.java文件放在其下面。
此時會報錯,因為沒有引入jar包,在package視圖下,將protobuf-java-2.4.1.jar引入,即可解決問題。

4.建立測試文件:
package com.sq.protobuf.test;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

import com.google.protobuf.;
import com.sq.protobuf.FirstProtobuf;

public class Test {
public static void main(String[] args) {

//序列化過程
//FirstProtobuf是生成類的名字,即proto文件中的java_outer_classname
//testBuf是裡面某個序列的名字,即proto文件中的message testBuf
FirstProtobuf.testBuf.Builder builder=FirstProtobuf.testBuf.newBuilder();
builder.setID(777);
builder.setUrl("shiqi");

//testBuf
FirstProtobuf.testBuf info=builder.build();

byte[] result = info.toByteArray() ;

String driver = "oracle.jdbc.driver.OracleDriver";
String url = "jdbc:oracle:thin:@10.64.59.12:1521/orcl";
String user = "parkingsystem";
String password = "parkingsystem";
try {
Class.forName(driver);
Connection conn = DriverManager.getConnection(url, user, password);

if(!conn.isClosed()){
System.out.println("Succeeded connecting to the Database!");

//此處只能使用prepareStatement
PreparedStatement ps = conn.prepareStatement("insert into test(id,test) values (1,?)");

//寫入資料庫,要把它改寫為流的形式
ByteArrayInputStream stream = new ByteArrayInputStream(result);
ps.setBinaryStream(1,stream,stream.available());
Statement statement = conn.createStatement();

Blob blob = null;
ps.execute();

////////////////上述完成將寫入資料庫的操作,資料庫中對應的欄位的屬性要設置為Blob

String sql = "select test from test";
ResultSet rs = statement.executeQuery(sql);
if(rs.next()){
blob = rs.getBlob("test");
}

byte[] s = blob.getBytes(1,(int)blob.length());

FirstProtobuf.testBuf testBuf = FirstProtobuf.testBuf.parseFrom(s);
System.out.println(testBuf);
conn.close();
}
}catch(Exception e) {
e.printStackTrace();
}

//反序列化過程
try {
FirstProtobuf.testBuf testBuf = FirstProtobuf.testBuf.parseFrom(result);
System.out.println(testBuf);
} catch ( e) {
e.printStackTrace();
}

}
}

發現可以將其序列化,插入到資料庫,並可以從資料庫出取出後,反序列化,內容可以正常顯示出來。

注意的就是2點:
1.不能用statement,否則無法插入blob類型的數據
2.為參數賦值時,要用
ByteArrayInputStream stream = new ByteArrayInputStream(result);
ps.setBinaryStream(1,stream,stream.available());

⑵ 序列化和反序列化

序列化(serialization)在計算機科學的數據處理中,是指將數據結構或對象狀態轉換成可取用格式(例如存成文件,存於緩沖,或經由網路中發送),以留待後續在相同或另一台計算機環境中,能恢復原先狀態的過程。依照序列化格式重新獲取位元組的結果時,可以利用它來產生與原始對象相同語義的副本。對於許多對象,像是使用大量引用的復雜對象,這種序列化重建的過程並不容易。面向對象中的對象序列化,並不概括之前原始對象所關系的函數。這種過程也稱為對象編組(marshalling)。從一系列位元組提取數據結構的反向操作,是反序列化(也稱為解編組、deserialization、unmarshalling)。

序列化在計算機科學中通常有以下定義:

序列化與反序列化為數據交換提供了可能,但是因為傳遞的是位元組碼,可讀性差。在應用層開發過程中不易調試,為了解決這種問題,最直接的想法就是將對象的內容轉換為字元串的形式進行傳遞。具體的傳輸格式可自行定義,但自定義格式有一個很大的問題——兼容性,如果引入其他系統的模塊,就需要對數據格式進行轉換,維護其他的系統時,還要先了解一下它的序列化方式。為了統一數據傳輸的格式,出現了幾種數據交換協議,如:JSON, Protobuf,XML。這些數據交換協議可視為是應用層面的序列化/反序列化。

如前所述,序列化和反序列化的出現往往晦澀而隱蔽,與其他概念之間往往相互包容。為了更好了讓大家理解序列化和反序列化的相關概念在每種協議裡面的具體實現,我們將一個例子穿插在各種序列化協議講解中。在該例子中,我們希望將一個用戶信息在多個系統裡面進行傳遞;在應用層,如果採用 .net 語言,所面對的類對象如下所示:

JSON中的元素都是鍵值對——key:value形式,鍵值對之間以":"分隔,每個鍵需用雙引號引起來,值的類型為String時也需要雙引號。其中value的類型包括:對象,數組,值,每種類型具有不同的語法表示。

基礎類型

對象

數組

說到XML就不得不介紹下SOAP(Simple Object Access protocol),SOAP 是一種被廣泛應用的,基於 XML 為序列化和反序列化協議的結構化消息傳遞協議。SOAP 在互聯網影響如此大,以至於我們給基於 SOAP 的解決方案一個特定的名稱 --Web service。SOAP 雖然可以支持多種傳輸層協議,不過 SOAP 最常見的使用方式還是 XML+HTTP。SOAP 協議的主要介面描述語言(IDL)是 WSDL(Web Service Description Language)。SOAP 具有安全、可擴展、跨語言、跨平台並支持多種傳輸層協議。如果不考慮跨平台和跨語言的需求,XML 的在某些語言裡面具有非常簡單易用的序列化使用方法,無需 IDL 文件和第三方編譯

實際使用中具體要使用哪個協議,我們可以從上列出的幾個特性進行綜合考慮

序列化協議一方面要能擺脫語言、平台的束縛;另一方面要在業界耳熟能詳應用廣泛。比如Java標準的對象序列化實現就不是這一條的好榜樣,你要一個C程序員將Java標准序列化實現的數據反序列化成對應結構體是一個很蛋疼的事情。相反,JSON就是一個很好的序列化協議,至少在這一條上算得上是佼佼者了。

序列化協議要能方便開發過程中的調試。做過二進制協議開發的同學一定深有體會,肉眼基本不可辨別序列化後的數據,需要藉助一些第三方的工具一點點分析。相對於二進制協議,文本協議就比較和藹可親了。

協議要能夠經得住時間的考驗。一般情況下採用公開流行的協議是不存在這個問題的,因為他們都被成千上萬的應用檢驗過了。特別要小心的是自定義協議,舉個反例,比如自定義一個類似於Java標准序列化協議的協議,由於當前業務沒有涉及到對象和對象之間的繼承關系,所以協議制定者沒有考慮對象繼承的情況。但是隨著業務的發展,系統中出現了繼承關系的實體類,某個同事不小心將這種對象的實例序列化,結果可想而知。協議不夠成熟,所以自定義協議需要考慮的因數很多。如果自己不是大牛,建議不要自定義序列化協議。

和穩定性差不多,滿足通用性條件的協議基本不會出現這個問題。問題還是會出現在自定義協議上。協議的成熟是一個漫長的過程,要經過不斷的測試。比如穩定性中出現的那個問題,協議將繼承關系的序列化加入,升級之後就能解決問題。但是要做到兼容以前的版本就不那麼容易了。協議的制定者也不是聖人,不可能考慮得那麼周全,但是一定要有一套可擴展的方案,這樣協議才能存活下來,慢慢迭代成穩定版本。

說道性能問題,無非就是時間和空間的博弈。序列化結果數據的大小,直接影響網路傳輸的帶寬和磁碟存儲的空間。序列化和反序列化過程所消耗的時間長短,影響系統的性能。幾種常用的協議性能的比較網上有很多,這里就不詳細介紹了。

閱讀全文

與java序列化protobuf相關的資料

熱點內容
區域網如何用ftp伺服器配置 瀏覽:70
程序員慣性思考模式 瀏覽:439
如何在個稅app上查身份證號 瀏覽:6
電視家app安裝在電視上怎麼安 瀏覽:889
怎麼將pdf格式轉化為圖片格式 瀏覽:637
伺服器拔掉raid卡怎麼裝系統 瀏覽:232
區域對稱加密演算法 瀏覽:245
數字轉漢字php 瀏覽:733
安卓源碼硬體驅動 瀏覽:208
痰證pdf 瀏覽:814
電腦怎麼把word文檔轉pdf 瀏覽:867
程序員那麼可愛有孩子了嗎 瀏覽:480
安卓文字折疊怎麼使用 瀏覽:885
創造一個app如何掙錢 瀏覽:801
php55vc11 瀏覽:642
抖音如何關閉蘋果app充值 瀏覽:332
python多個文件調用 瀏覽:792
java演算法和數據結構 瀏覽:465
糖豆視頻的文件夾 瀏覽:654
php的頭部文件一般在哪個文件里 瀏覽:560