나는 모든 사람들이 JSON이 무엇인지 알고 있다고 믿는다. 모르는 경우 실제로 나옵니다. GOOGLE. 나는 여기에 아무것도 소개하지 않을 것입니다.
나는 모든 사람들이 프로토 버퍼에 대해 거의 듣지 않는다고 생각하지만, Google에서 끝나면 모든 사람들이 그것을 시도하는 데 관심이 있다고 생각합니다. 결국 Google 수출은 대부분 고품질 제품입니다.
Protobuffer는 JSON과 유사한 전송 프로토콜입니다. 실제로, 그것은 프로토콜이라고 말할 수 없으며 단지 데이터 전송 일입니다.
그렇다면 그것과 JSON의 차이점은 무엇입니까?
교차 언어, 이것은 장점 중 하나입니다. 컴파일러 인 PROTOC과 함께 제공되며, 이로는 컴파일되며 Java, Python 및 C ++ 코드로 컴파일 할 수 있습니다. 당분간이 세 가지만이 있으므로 당분간 다른 사람에 대해 생각하지 말고 다른 코드를 쓰지 않고 직접 사용할 수 있습니다. 구문 분석 된 사람들조차도 이미 그들과 함께 제공됩니다. JSON은 물론 교차 언어이지만이 교차 언어는 작문 코드를 기반으로합니다.
더 알고 싶다면 확인할 수 있습니다.
https://developers.google.com/protocol-buffers/docs/overview
좋아, 더 이상 고민하지 않고, 왜 우리가 Protobuffer (이하 GPB라고 함)와 JSON을 비교 해야하는 이유를 살펴 보겠습니다.
1. JSON은 특정 형식을 가지고 있으며 문자에 존재하기 때문에 여전히 데이터 양에 압축의 여지가 있습니다. GPB의 빅 데이터의 양이 JSON의 빅 데이터 양보다 훨씬 적은 경우 아래 예제를 볼 수 있습니다.
2. JSON 라이브러리 간의 효율 차이는 상당히 크며 Jackson 라이브러리와 GSON간에 약 5-10의 간격이 있습니다 (오류가 있으면 한 번만 테스트되었습니다. GPB는 하나만 필요하며 소위 여러 라이브러리 사이에는 차이가 없습니다. 물론,이 점은 숫자를 위해 구성되어 있으며 무시할 수 있습니다.
대화는 싸다. 코드를 보여주세요.
프로그래밍 세계에서 코드는 항상 왕이므로 코드로 가자.
코드를 업로드하기 전에 먼저 프로토 버퍼를 다운로드해야합니다.
https://github.com/google/protobuf
1. 우선, GPB는 프로토 파일이라고하는 유사한 클래스 정의가있는 파일이 있어야합니다.
학생과 교사의 예를 들어 보자.
다음 두 파일이 있습니다 : Student.proto
옵션 java_package = "com.shun"; 옵션 java_outer_classname = "StudentProto"; 메시지 학생 {필수 int32 id = 1; 선택적 문자열 이름 = 2; 선택적 int32 Age = 3; } </span> 교사 .Proto
"학생 .proto"수입; 옵션 java_package = "com.shun"; 옵션 java_outer_classname = "TeacherProto"; 메시지 교사 {필수 int32 id = 1; 선택적 문자열 이름 = 2; 반복 된 학생 학생 _list = 3; } </span> 여기서 우리는 몇 가지 이상한 것들을 만났습니다.
가져 오기, int32, 반복, 필수, 선택 사항, 옵션 등
1) 가져 오는 것은 다른 프로토 파일을 가져 오는 것을 의미합니다
2) 필수 및 선택 사항은 필드가 선택 사항인지를 나타냅니다. 이는 필드에 값이 있거나없는 경우 Protobuffer가 수행 할 처리가 결정됩니다. 필요한 경우, 처리 할 때 필드는 값을 전달하지 않으면 오류 가보고됩니다. 선택 사항이 표시되면 값이 전송되지 않으면 문제가 없습니다.
3) 나는 당신이 반복적으로 이해할 수 있다고 생각합니다. 즉, 반복되는지 여부는 Java의 목록과 유사합니다.
4) 메시지는 클래스와 동일합니다
5) 옵션은 옵션을 나타내며, 여기서 java_package는 패키지 이름, 즉 Java 코드를 생성 할 때 사용되는 패키지 이름을 나타냅니다. java_outer_classname은 클래스 이름입니다. 이 클래스 이름은 아래 메시지의 클래스 이름과 동일 할 수 없습니다.
다른 옵션 및 관련 유형은 공식 문서를 방문하십시오.
2.이 문서를 통해 우리는 무엇을 할 수 있습니까?
위에 다운로드 한 컴파일러를 기억하십시오. 압축을 풀고 우리는 protoc.exe를 얻습니다. 물론 이것은 창을 기반으로합니다. 나는 다른 시스템을하지 않았다. 관심이 있으시면 시도해 볼 수 있습니다.
경로에 추가 (추가하기 쉽지 않든, 불편 함) 위 파일을 통해 필요한 클래스 파일을 생성 할 수 있습니다.
protoc -java_out = 저장 소스 코드로가는 경로 -proto_path = 프로토 파일로가는 경로 프로토 특정 파일
-proto_path 단일 파일이 아닌 프로토 파일의 폴더 경로를 지정하며 주로 가져 오기 파일 검색에 사용되며 생략 할 수 있습니다.
소스 코드를 d :/protobuffervsjson/src에 넣어야하는 경우 내 프로토 파일은 d :/protofiles에 저장됩니다.
내 컴파일 명령은 다음과 같습니다.
protoc -java_out = d :/protobuffervsjson/src d : /protofiles/teacher.proto d : /protofiles/student.proto
여기서 마지막 파일에서 컴파일 해야하는 모든 파일을 지정해야합니다.
컴파일 후 생성 된 파일을 볼 수 있습니다.
코드가 게시되지 않았습니다. 개인적으로 살펴볼 수 있습니다. 코드에는 많은 빌더가 있습니다. 나는 그것이 그것이 한 눈에 빌더 모드라는 것을 알고있을 것이라고 믿는다.
현재 코드를 프로젝트에 붙여 넣을 수 있으며 물론 많은 오류가 있습니다.
이전에 다운로드 한 소스 코드를 기억하십니까? 압축을 풀고 무자비하지 마십시오. 그런 다음 SRC/Main/Java/를 찾아 프로젝트에 복사하십시오. 물론, 당신은 개미 나 Maven을 컴파일 할 수 있지만, 나는이 두 가지에 익숙하지 않으므로 더 이상 못 생겼을 것입니다. 나는 여전히 프로젝트에 직접 복사하는 데 익숙합니다.
코드 오류, 하하, 정상. 어떤 이유로 Google은 우리를 위해 그러한 구덩이를 남기라고 주장합니다.
Protobuffer 디렉토리의 /java로 돌아가서 readme.txt를보고 문장을 찾으십시오.
그것을 본 후, 나는이 코드가 마치 마치 마치 마치 마치 마치 마치 조금 이상하다고 생각합니다. 어쨌든, 나는 그것을 실행하지 않았고 나의 명령은 다음과 같습니다.
<span style = "font-size : 16px;"> protoc -java_out = 또는 코드가 배치 된 프로토 파일의 경로 (여기서 descriptor.proto 파일의 경로) </span>
실행 후 코드에 오류가 없음을 알 수 있습니다.
3. 다음 단계는 물론 테스트입니다.
먼저 GPB 쓰기 테스트를 수행하겠습니다.
패키지 com.shun.test; import java.io.fileoutputStream; import java.io.ioexception; java.util.arraylist 가져 오기; Java.util.list 가져 오기; import com.shun.studentproto.student; com.shun.teacherproto.teacher import; public class protowritetest {public static void main (string [] args)은 ioexception {whening.builder stubuilder = Student.newbuilder (); 수염병. 세트 (25); stubuilder.setid (11); stubuilder.setName ( "Shun"); // 구성 목록 목록 목록 <TodyTubUilDerlist = New ArrayList <tudent> (); stubuilderlist.add (stubuilder.build ()); Teacher.builder TeuBuilder = 교사 .newbuilder (); teaBuilder.SetID (1); teaBuilder.setName ( "TestTea"); TeaBuilder.addallstudentlist (stubuilderlist); // 파일 파일로 gpb를 쓰기 FileOutputStream fos = new FileOutputStream ( "c : //users//shun//desktop//test//test.protoout"); teaBuilder.build (). Writeto (Fos); fos.close (); }} </span> 파일을 살펴 보겠습니다. 예상치 못한 일이 발생하지 않으면 생성되어야합니다.
그것이 생성 된 후에, 우리는 그것을 다시 읽어야합니다.
패키지 com.shun.test; import java.io.fileInputStream; import java.io.filenotfoundException; import java.io.ioexception; import com.shun.studentproto.student; com.shun.teacherproto.teacher import; public class protoreadtest {public static void main (String [] args)은 filenotfoundexception, ioexception {교사 교사 = 교사. System.out.println ( "교사 ID :" + 교사 .getId () + ", 이름 :" + 교사 .getName ()); for (학생 stu : teacher.getStudentListList ()) {System.out.println ( "학생 id :" + stu.getId () + ", 이름 :" + stu.getName () + ", age :" + stu.getage ()); }}}} </span> GPB에 의해 생성 된 모든 코드가 우리를 위해 수행되므로 코드는 매우 간단합니다.
위의 기본 사용량을 알고 있습니다. GPB와 JSON 생성 파일 크기의 차이점에 중점을 둘 것입니다. 나는 여기에 JSON의 자세한 코드를 게시하지 않을 것입니다. 나중에 예제를 게시하겠습니다. 관심이 있으시면 다운로드 할 수 있습니다.
여기서 우리는 GSON을 사용하여 JSON을 구문 분석합니다. 다음은 개체를 JSON으로 변환하고 파일을 작성하는 코드입니다.
나는 두 클래스 학생과 교사의 기본 정의를 작성하지 않을 것입니다. 원하는대로 코드는 다음과 같습니다.
패키지 com.shun.test; import java.io.filewriter; import java.io.ioexception; java.util.arraylist 가져 오기; Java.util.list 가져 오기; import com.google.gson.gson; com.shun.student import; com.shun.teacher import; public class gsonwritetest {public static void main (string [] args)은 ioexception {Student stu = new Student (); Stu.setage (25); stu.setid (22); stu.setname ( "Shun"); List <tudent> stulist = new ArrayList <student> (); stulist.add (stu); 교사 교사 = 새로운 교사 (); Teacher.setId (22); Teacher.setName ( "Shun"); Teacher.setstulist (Stulist); 문자열 결과 = new Gson (). Tojson (교사); filewriter fw = new filewriter ( "c : // users // shun/goodtop // test // json"); fw.write (결과); fw.close (); }} </span> 다음으로 공식적으로 실제 테스트 코드를 입력합니다. 처음에는 목록에 객체를 넣었습니다. 다음으로 GPB와 JSON이 생성 한 파일 크기를 차례로 테스트합니다.
이전 GPB 코드를 개선하고 다른 수의 목록을 생성하고 파일을 재생하도록하십시오.
패키지 com.shun.test; import java.io.fileoutputStream; import java.io.ioexception; java.util.arraylist 가져 오기; Java.util.list 가져 오기; import com.shun.studentproto.student; com.shun.teacherproto.teacher import; Public Class ProtoWritetest {public static final int size = 100; public static void main (String [] args)은 ioexception {// 구성 목록 목록 <TudlyDuilDerList = new ArrayList <tudent> (); for (int i = 0; i <size; i ++) {student.builder stubuilder = Student.newbuilder (); 수염병. 세트 (25); stubuilder.setid (11); stubuilder.setName ( "Shun"); stubuilderlist.add (stubuilder.build ()); } el teaBuilder.SetID (1); teaBuilder.setName ( "TestTea"); TeaBuilder.addallstudentlist (stubuilderlist); // 파일 파일에 gpb를 쓰기 FileOutputStream FOS = 새 FileOutputStream ( "c : // users // shun // goodtop // test // proto-" + size); teaBuilder.build (). Writeto (Fos); fos.close (); }} </span> 여기의 크기는 위에서 언급 한 테스트 번호로 변경되며 다음을 얻을 수 있습니다.
그런 다음 JSON 테스트 코드를 살펴 보겠습니다.
패키지 com.shun.test; import java.io.filewriter; import java.io.ioexception; java.util.arraylist 가져 오기; Java.util.list 가져 오기; import com.google.gson.gson; com.shun.student import; com.shun.teacher import; 공개 클래스 GsonWritetest {public static final int size = 100; public static void main (string [] args)은 ioexception {list <tudent> stulist = new Arraylist <tudent> (); for (int i = 0; i <size; i ++) {Student stu = new Student (); Stu.setage (25); stu.setid (22); stu.setname ( "Shun"); stulist.add (stu); } 교사 교사 = 새로운 교사 (); Teacher.setId (22); Teacher.setName ( "Shun"); Teacher.setstulist (Stulist); 문자열 결과 = new Gson (). Tojson (교사); filewriter fw = new filewriter ( "C : // users // shun // goodtop // test // json" + size); fw.write (결과); fw.close (); }} </span> 동일한 방법이 크기를 수정하고 해당 테스트를 수행하는 데 사용됩니다.
JSON과 GPB의 파일 크기가 데이터 볼륨이 점차 증가 할 때 큰 차이가 있음을 분명히 알 수 있습니다. JSON은 분명히 훨씬 더 큽니다.
위의 표는 더 명확해야합니다. 빅 데이터의 GPB는 매우 지배적이지만 일반적으로 클라이언트와 서버는 그러한 빅 데이터와 직접 상호 작용하지 않습니다. 빅 데이터는 주로 서버 전송에서 발생합니다. 필요에 직면하면 매일 수백 M의 로그 파일을 다른 서버로 전송해야합니다. 여기에서 GPB가 큰 도움이 될 수 있습니다.
그것은 깊이 비교라고 할 수 있지만, 주요 비교는 크기이며 시간 비교는 그리 많지 않으며 큰 차이도 없습니다.
기사에서 선택한 GSON 파서의 경우 관심있는 친구가 Jackson 또는 Fastjson 또는 기타를 선택할 수 있지만 생성 된 파일 크기는 동일하지만 구문 분석 시간은 다릅니다.