您的位置:首页 > 理论基础 > 计算机网络

ProtoBuf

2015-07-28 10:46 621 查看
由于JDK传统的序列化,有如下致命的缺点

1,无法夸语言

2,序列化后,码流过大

3,序列化效率过低(传统的序列化性能只有二进制编码的7%左右)

google的ProtoBuf,能够很好的解决以上问题。

由于Protobuf受到推崇,故尝试采用protobuf来摒弃传统的xml进行传输数据。

首先,需要下载的关于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.InvalidProtocolBufferException;

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 (InvalidProtocolBufferException e) {
e.printStackTrace();
}

}

}

发现可以将其序列化,插入到数据库,并可以从数据库出取出后,反序列化,内容可以正常显示出来。

注意的就是2点:

1.不能用statement,否则无法插入blob类型的数据

2.为参数赋值时,要用

ByteArrayInputStream stream =  new ByteArrayInputStream(result);
ps.setBinaryStream(1,stream,stream.available());
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 网络编程 编码