Ich glaube, jeder weiß, was JSON ist. Wenn Sie es nicht wissen, ist es wirklich raus. Google. Ich werde hier nichts vorstellen.
Ich denke, jeder hört selten von Protobuffer, aber wenn dies von Google geschehen ist, wird ich glaube, dass jeder daran interessiert sein wird, es zu versuchen. Schließlich sind Google-Exporte meist hochwertige Produkte.
Der Protobuffer ist ein Übertragungsprotokoll, das JSON ähnelt. Tatsächlich kann man nicht als Protokoll gesagt werden, es ist nur eine Datenübertragungssache.
Was ist der Unterschied zwischen ihm und JSON?
Cross-Language, dies ist einer seiner Vorteile. Es wird mit einem Compiler, Protoc, geliefert, der nur damit zusammengestellt werden muss, und kann in Java-, Python- und C ++ - Code zusammengestellt werden. Es gibt vorerst nur diese drei. Denken Sie also vorerst nicht an die anderen nach, und dann können Sie sie direkt verwenden, ohne einen anderen Code zu schreiben. Sogar die analysierten kommen bereits mit ihnen. JSON ist natürlich Cross-Language, aber diese Cross-Language basiert auf dem Schreiben von Code.
Wenn Sie mehr wissen möchten, können Sie es überprüfen:
https://developers.google.com/protocol-bufers/docs/overview
Okay, ohne weiteres schauen wir uns an, warum wir Protobuffer (im Folgenden als GPB bezeichnet) und JSON vergleichen müssen.
1. Da JSON ein bestimmtes Format hat und in Charakteren existiert, gibt es immer noch Raum für Komprimierung in der Datenmenge. Wenn die Menge an Big Data auf GPB viel kleiner ist als die von JSON, können wir das folgende Beispiel sehen.
2. Der Effizienzunterschied zwischen JSON-Bibliotheken ist ziemlich groß, und es gibt eine Lücke von etwa 5-10 zwischen Jackson-Bibliotheken und GSON (dies wurde nur einmal getestet, wenn ein Fehler vorliegt, bitte tlät). GPB benötigt nur einen, und es gibt keinen Unterschied zwischen sogenannten mehreren Bibliotheken. Natürlich ist dieser Punkt nur für die Zahlen wettgemacht und kann ignoriert werden.
Reden ist billig, zeig mir einfach den Code.
In der Programmierwelt ist Code immer der König. Gehen wir also einfach zum Code.
Bevor Sie den Code hochladen, müssen Sie den Protobuffer zuerst hier herunterladen:
https://github.com/google/protobuf
1. Zunächst muss GPB eine Datei mit ähnlichen Klassendefinitionen haben, die als Proto -Datei bezeichnet wird.
Nehmen wir das Beispiel von Schülern und Lehrern, um ein Beispiel zu geben:
Wir haben die folgenden zwei Dateien: student.proto
Option java_package = "com.shun"; Option java_outer_classname = "studentProto"; Message Student {Erforderlich int32 id = 1; optionaler Zeichenfolge Name = 2; optional int32 Alter = 3; } </span> Lehrer.Proto
importieren "student.proto"; Option java_package = "com.shun"; Option java_outer_classname = "lernproto"; Nachrichtenlehrer {Erforderlich int32 id = 1; optionaler Zeichenfolge Name = 2; wiederholte student student_list = 3; } </span> Hier haben wir einige seltsame Dinge begegnet:
importieren, int32, wiederholt, erforderlich, optional, Option usw.
1) Import bedeutet, andere Protodateien importieren zu können
2) Erforderlich und optional gibt an, ob das Feld optional ist. Dies bestimmt, welche Verarbeitung vom Protobuffer durchgeführt wird, wenn das Feld einen Wert hat oder nicht. Bei Bedarf ist markiert, aber bei der Verarbeitung wird das Feld den Wert nicht übergeben, wird ein Fehler gemeldet. Wenn optional markiert ist, wird kein Wert übertragen, es wird kein Problem geben.
3) Ich glaube, Sie können wiederholt verstehen, was bedeutet, ob es wiederholt wird, sie ähnelt der Liste in Java.
4) Nachricht entspricht der Klasse
5) Die Option stellt die Option dar, wobei Java_Package den Paketnamen darstellt, dh den Paketnamen, der beim Generieren von Java -Code verwendet wird. Java_outer_ClassName ist der Klassenname. Beachten Sie, dass dieser Klassenname nicht mit dem Klassennamen in der folgenden Nachricht übereinstimmen kann.
In Bezug auf andere Optionen und verwandte Typen besuchen Sie bitte die offizielle Dokumentation.
2. Was können wir mit diesen Dokumenten tun?
Denken Sie an den oben heruntergeladenen Compiler. Entpeak es und wir bekommen einen Protoc.exe. Dies basiert natürlich auf Windows. Ich habe keine anderen Systeme gemacht. Wenn Sie interessiert sind, können Sie es ausprobieren.
Zu Pfad hinzufügen (es ist einfach hinzuzufügen oder nicht, es ist nur unpraktisch), und dann können Sie die Klassendatei generieren, die wir über die obige Datei benötigen.
Protoc -Java_Out = Pfad zum Speichern von Quellcode --Proto_Path = Pfad zur Proto -Proto -Spezifische Datei
--Proto_Path gibt den Ordnerpfad der Proto-Datei an, nicht eine einzige Datei, die hauptsächlich für die Importdateisuche verwendet wird und kann weggelassen werden
Wenn ich den Quellcode in d:/protobuffervsjson/src einfügen muss, wird meine Proto -Datei in d:/protfile gespeichert
Dann lautet mein Kompilierungsbefehl:
Protoc -Java_Out = d:/protobuffervsjson/src d: /protfiles/teacher.proto d: /protofiles/student.proto
Beachten Sie, dass wir in der letzten Datei hier alle Dateien angeben müssen, die zusammengestellt werden müssen.
Nach der Zusammenstellung können Sie die generierte Datei sehen.
Der Code ist nicht zu viel veröffentlicht. Sie können privat einen Blick darauf werfen. Es gibt viele Bauherren im Code. Ich glaube, Sie werden wissen, dass es der Bauunternehmermodus auf einen Blick ist.
Zu diesem Zeitpunkt können Sie den Code in Ihr Projekt einfügen, und natürlich gibt es viele Fehler.
Erinnerst du dich an den Quellcode, den wir zuvor heruntergeladen haben? Entpeak es, sei nicht rücksichtslos. Suchen Sie dann SRC/Main/Java/, um einen von ihnen in Ihr Projekt zu kopieren. Natürlich können Sie auch Ameise oder Maven zusammenstellen, aber ich bin mit diesen beiden Dingen nicht vertraut, also werde ich nicht mehr hässlich sein. Ich bin es immer noch gewohnt, sie direkt an das Projekt zu kopieren.
Der Codefehler, haha, normal. Aus irgendeinem Grund besteht Google darauf, eine solche Grube für uns zu verlassen.
Gehen Sie zurück zu /Java im Protobuffer -Verzeichnis und sehen Sie sich einen Readme.txt an und finden Sie einen Satz:
Nachdem ich es mir angesehen habe, bin ich der Meinung, dass dieser Code etwas seltsam sein wird, als wäre er falsch. Wie auch immer, ich habe es nicht ausgeführt und mein Befehl lautet:
<span style = "Schriftgröße: 16px;"> Protoc-Java_out = oder der Pfad der Proto-Datei, in der der Code platziert wird (hier ist der Pfad der Datei Descriptor.Proto) </span>
Nach der Ausführung können wir feststellen, dass der Code keine Fehler gibt.
3. Der nächste Schritt ist natürlich Tests.
Lassen Sie uns zuerst einen GPB -Schreibtest durchführen:
Paket com.shun.test; importieren java.io.fileoutputStream; importieren java.io.ioException; Import Java.util.ArrayList; importieren java.util.list; import com.shun.studentProto.student; Import Com.shun.TeacherProto.Teacher; public class ProtoWRitetest {public static void main (String [] args) löst ioException {student.builder sturilder = student.newbuilder () aus; Stubuilder.Setage (25); stubuilder.setid (11); stubuilder.setName ("Shun"); // LISTE LISTE CONSTRUCT LIST <Stud Student> StubuilderList = New ArrayList <Student> (); stubuilderlist.add (stubuilder.build ()); Lehrer.Builder Teebuilder = Lehrer.Newbuilder (); Teebuilder.Setid (1); Teebuilder.SetName ("Testtea"); Teebuilder.AddallstudentList (StubuilderList); // GPB in Datei -DateiOutputStream schreiben fos = new FileOutputStream ("c: //users//shun//desktop//test//test.protoout"); teabuilder.build (). writeTo (fos); fos.close (); }} </span> Schauen wir uns die Datei an, wenn nichts Unerwartetes passiert, hätte sie generiert werden sollen.
Nachdem es generiert wurde, müssen wir es zurücklesen.
Paket com.shun.test; import Java.io.FileInputStream; importieren java.io.filenotfoundException; importieren java.io.ioException; import com.shun.studentProto.student; Import Com.shun.TeacherProto.Teacher; public class protoreadtest {public static void main (String [] args) löst FilenotFoundException, ioException aus {lehrer lehrer = lehrer.parsefrom (neuer FileInputStream ("c: //users//shun//desktop//test/test.protoout"); System.out.println ("Lehrer -ID:" + lehrer.getId () + ", Name:" + lehrer.getName ()); für (Schüler stu: lehre.getStudentList ()) {System.out.println ("Student ID:" + stu.getid () + ", Name:" + stu.getName () + ", Alter:" + stu.getage ()); }}}} </span> Der Code ist sehr einfach, da der gesamte von GPB generierte Code für uns durchgeführt wird.
Das obige kennt die grundlegende Verwendung. Wir werden uns auf den Unterschied zwischen GPB und JSON -generierten Dateigrößen konzentrieren. Ich werde den detaillierten Code von JSON hier nicht veröffentlichen. Ich werde später ein Beispiel veröffentlichen. Wenn Sie interessiert sind, können Sie es herunterladen.
Hier verwenden wir GSON, um JSON zu analysieren. Das Folgende ist nur der Code zum Konvertieren des Objekts in JSON und das Schreiben der Datei:
Ich schreibe nicht die grundlegenden Definitionen der beiden Schüler Schüler und Lehrer. Tun Sie es einfach, wie Sie möchten, der Code ist wie folgt:
Paket com.shun.test; Import Java.io.FileWriter; importieren java.io.ioException; Import Java.util.ArrayList; importieren java.util.list; import com.google.gson.gson; import com.shun.student; com.shun.Teacher importieren; public class gsonwritetest {public static void main (String [] args) löst ioException {student stu = new Student () aus; Stu.Setage (25); stu.setid (22); stu.setname ("Shun"); LIST <Student> stulist = new ArrayList <Student> (); stulist.add (stu); Lehrer Lehrer = neuer Lehrer (); Teacher.Setid (22); Teacher.SetName ("Shun"); Lehrer.SetStulist (Stulist); String result = new gson (). Tojson (Lehrer); Filewriter fw = neuer FileWriter ("c: // user // shun/desktop // test // json"); fw.write (Ergebnis); fw.close (); }} </span> Als nächstes geben wir offiziell unseren echten Testcode ein. Am Anfang haben wir einfach ein Objekt in die Liste eingerichtet. Als nächstes testen wir die von GPB und JSON erzeugten Dateigrößen.
Verbessern Sie den vorherigen GPB -Code und generieren Sie eine unterschiedliche Anzahl von Listen und regenerieren Sie Dateien:
Paket com.shun.test; importieren java.io.fileoutputStream; importieren java.io.ioException; Import Java.util.ArrayList; importieren java.util.list; import com.shun.studentProto.student; Import Com.shun.TeacherProto.Teacher; public class protowritest {public static final int size = 100; public static void main (String [] args) löst IOException {// constructlistliste <Student> stubuilderlist = new ArrayList <Student> () aus; für (int i = 0; i <size; i ++) {student.builder stubuilder = student.newbuilder (); Stubuilder.Setage (25); stubuilder.setid (11); stubuilder.setName ("Shun"); stubuilderlist.add (stubuilder.build ()); } Lehrer.builder teebuilder = lehrer.newbuilder (); Teebuilder.Setid (1); Teebuilder.SetName ("Testtea"); Teebuilder.AddallstudentList (StubuilderList); // GPB in Datei-DateiOutputStream schreiben fos = new FileOutputStream ("C: // Benutzer // Shun // Desktop // test // proto-" + size); teabuilder.build (). writeTo (fos); fos.close (); }} </span> Die Größe hier wird auf die Testnummer geändert, die wir oben nacheinander gesagt haben, und Sie können Folgendes erhalten:
Schauen wir uns dann den JSON -Testcode an:
Paket com.shun.test; Import Java.io.FileWriter; importieren java.io.ioException; Import Java.util.ArrayList; importieren java.util.list; import com.google.gson.gson; import com.shun.student; com.shun.Teacher importieren; public class gsonwritetest {public static final int size = 100; public static void main (String [] args) löst ioException {list <Student> stulist = new ArrayList <Studenten> () aus; für (int i = 0; i <size; i ++) {student stu = new student (); Stu.Setage (25); stu.setid (22); stu.setname ("Shun"); stulist.add (stu); } Lehrer Lehrer = neuer Lehrer (); Teacher.Setid (22); Teacher.SetName ("Shun"); Lehrer.SetStulist (Stulist); String result = new gson (). Tojson (Lehrer); Filewriter fw = neuer FileWriter ("C: // Benutzer // Shun // Desktop // test // json" + Größe); fw.write (Ergebnis); fw.close (); }} </span> Die gleiche Methode wird verwendet, um die Größe zu ändern und entsprechende Tests durchzuführen.
Es ist deutlich zu erkennen, dass die Dateigröße von JSON und GPB einen großen Unterschied aufweist, wenn das Datenvolumen allmählich zunimmt. JSON ist offensichtlich viel größer.
Die obige Tabelle sollte klarer sein. GPB von Big Data ist sehr dominant, aber im Allgemeinen interagieren der Client und der Server nicht direkt mit solch Big Data. Big Data tritt hauptsächlich in der Serverübertragung auf. Wenn Sie den Anforderungen konfrontiert sind, müssen Sie jeden Tag Hunderte von M -Protokolldateien auf einen anderen Server übertragen, dann ist der GPB hier eine große Hilfe.
Es soll ein Tiefenvergleich sein, aber der Hauptvergleich ist die Größe, und der Zeitvergleich ist nicht zu stark, und es gibt auch keinen großen Unterschied.
Für den in dem Artikel ausgewählten GSON -Parser können interessierte Freunde Jackson oder Fastjson oder andere auswählen, aber die generierte Dateigröße ist gleich, aber die Analysezeit ist unterschiedlich.