Saya percaya semua orang tahu apa itu JSON. Jika Anda tidak tahu, itu benar -benar keluar. Google. Saya tidak akan memperkenalkan apapun di sini.
Saya kira semua orang jarang mendengar tentang protobuffer, tetapi jika itu dilakukan oleh Google, saya percaya semua orang akan tertarik untuk mencobanya. Lagi pula, ekspor Google sebagian besar adalah produk berkualitas tinggi.
Protobuffer adalah protokol transmisi yang mirip dengan JSON. Bahkan, itu tidak dapat dikatakan sebagai protokol, itu hanya masalah transmisi data.
Jadi apa perbedaan antara itu dan JSON?
Bahasa silang, ini adalah salah satu keunggulannya. Muncul dengan kompiler, protoc, yang hanya perlu dikompilasi dengannya, dan dapat dikompilasi menjadi kode Java, Python, dan C ++. Hanya ada ketiganya untuk saat ini, jadi jangan pikirkan yang lain untuk saat ini, dan kemudian Anda dapat menggunakannya secara langsung tanpa menulis kode lain. Bahkan orang -orang yang diuraikan sudah ikut dengan mereka. JSON tentu saja adalah bahasa silang, tetapi bahasa silang ini didasarkan pada kode penulisan.
Jika Anda ingin tahu lebih banyak, Anda dapat memeriksanya:
https://developers.google.com/protocol-buffers/docs/overview
Oke, tanpa basa -basi lagi, mari kita lihat mengapa kita perlu membandingkan protobuffer (selanjutnya disebut GPB) dan JSON.
1. Karena JSON memiliki format tertentu dan ada dalam karakter, masih ada ruang untuk kompresi dalam jumlah data. Ketika jumlah data besar pada GPB jauh lebih kecil dari JSON, kita dapat melihat contoh di bawah ini.
2. Perbedaan efisiensi antara perpustakaan JSON cukup besar, dan ada celah sekitar 5-10 antara Perpustakaan Jackson dan GSON (ini hanya diuji sekali, jika ada kesalahan, tolong patikan). GPB hanya membutuhkan satu, dan tidak ada perbedaan antara apa yang disebut beberapa perpustakaan. Tentu saja, poin ini hanya dibuat untuk angka -angka, dan itu bisa diabaikan.
Bicara itu murah, tunjukkan saja kodenya.
Di dunia pemrograman, kode selalu menjadi raja, jadi mari kita pergi ke kode.
Sebelum mengunggah kode, Anda perlu mengunduh protobuffer terlebih dahulu, di sini:
https://github.com/google/protobuf
1. Pertama -tama, GPB perlu memiliki file dengan definisi kelas yang sama, yang disebut file proto.
Mari kita ambil contoh siswa dan guru untuk membuat contoh:
Kami memiliki dua file berikut: Student.proto
opsi java_package = "com.shun"; opsi java_outer_classname = "studentproto"; Pesan Siswa {Diperlukan Int32 ID = 1; nama string opsional = 2; Usia int32 opsional = 3; } </span> Teacher.Proto
impor "student.proto"; opsi java_package = "com.shun"; opsi java_outer_classname = "TeacherProto"; Guru Pesan {wajib Int32 id = 1; nama string opsional = 2; Students Student_list yang diulang = 3; } </span> Di sini kami menemukan beberapa hal aneh:
Impor, int32, diulang, diperlukan, opsional, opsi, dll.
1) Impor berarti mengimpor file proto lainnya
2) Diperlukan dan opsional menunjukkan apakah bidangnya opsional. Ini menentukan pemrosesan apa yang akan dilakukan oleh protobuffer jika bidang memiliki nilai atau tidak. Jika diperlukan ditandai, tetapi saat pemrosesan, bidang tidak melewati nilainya, kesalahan akan dilaporkan; Jika opsional ditandai, tidak ada nilai yang akan ditransmisikan, tidak akan ada masalah.
3) Saya yakin Anda dapat memahami berulang, yang berarti apakah itu diulang, itu mirip dengan daftar di Java.
4) Pesan setara dengan kelas
5) Opsi mewakili opsi, di mana java_package mewakili nama paket, yaitu nama paket yang digunakan saat menghasilkan kode java. java_outer_classname adalah nama kelas. Perhatikan bahwa nama kelas ini tidak boleh sama dengan nama kelas dalam pesan di bawah ini.
Adapun opsi lain dan jenis terkait, silakan kunjungi dokumentasi resmi.
2. Dengan dokumen -dokumen ini, apa yang bisa kita lakukan?
Ingat kompiler yang diunduh di atas. Buka ritsleting dan kami mendapatkan protoc.exe. Tentu saja, ini didasarkan pada Windows. Saya tidak melakukan sistem lain. Jika Anda tertarik, Anda dapat mencobanya.
Tambahkan ke jalur (mudah untuk ditambahkan atau tidak, itu hanya tidak nyaman), dan kemudian Anda dapat menghasilkan file kelas yang kami butuhkan melalui file di atas.
protoc --java_out = path to store kode sumber --proTo_path = path ke file proto proto file spesifik
--proTo_path Menentukan jalur folder file proto, bukan satu file, itu terutama digunakan untuk pencarian file impor, dan dapat dihilangkan
Jika saya perlu memasukkan kode sumber di d:/protobuffervsjson/src, file proto saya disimpan dalam d:/protofiles
Maka perintah kompilasi saya adalah:
protoc --java_out = d:/protobuffervsjson/src d: /protofiles/teacher.proto d: /protofiles/student.proto
Perhatikan bahwa di file terakhir di sini, kita perlu menentukan semua file yang perlu dikompilasi.
Setelah kompilasi, Anda dapat melihat file yang dihasilkan.
Kode tidak diposting, terlalu banyak. Anda dapat melihatnya secara pribadi. Ada banyak pembangun dalam kode. Saya yakin Anda akan tahu itu adalah mode pembangun sekilas.
Pada saat ini, Anda dapat menempelkan kode ke dalam proyek Anda, dan tentu saja, ada banyak kesalahan.
Ingat kode sumber yang kami unduh sebelumnya? Buka ritsleting, jangan kejam. Kemudian temukan SRC/Main/Java/untuk menyalin salah satunya ke proyek Anda. Tentu saja, Anda juga dapat mengkompilasi semut atau pakar, tetapi saya tidak terbiasa dengan dua hal ini, jadi saya tidak akan menjadi jelek lagi. Saya masih terbiasa menyalinnya langsung ke proyek.
Kesalahan kode, haha, normal. Untuk beberapa alasan, Google bersikeras untuk meninggalkan lubang seperti itu untuk kita.
Kembali ke /java di direktori protobuffer dan lihat readme.txt, dan temukan kalimat:
Setelah melihatnya, saya merasa kode ini akan sedikit aneh, seolah -olah itu salah. Ngomong -ngomong, saya tidak menjalankannya, dan perintah saya adalah:
<span style = "font-size: 16px;"> protoc --java_out = atau jalur file proto di mana kode ditempatkan (berikut adalah jalur file deskriptor.proto) </span>
Setelah eksekusi, kita dapat melihat bahwa tidak ada kesalahan dalam kode.
3. Langkah selanjutnya tentu saja pengujian.
Mari kita melakukan tes tulis GPB terlebih dahulu:
paket com.shun.test; impor java.io.fileoutputStream; impor java.io.ioException; impor java.util.arraylist; impor java.util.list; impor com.shun.studentproto.student; impor com.shun.teacherproto.teacher; kelas publik ProtowRitetest {public static void main (string [] args) melempar ioException {student.builder stubuilder = student.newbuilder (); stubuilder.setage (25); stubuilder.setid (11); stubuilder.setname ("shun"); // Daftar Daftar Bangun <Sahasiswa> stubuilderlist = new ArrayList <Shown> (); stubuilderlist.add (stubuilder.build ()); Guru.builder tehuilder = Teacher.NewBuilder (); Teabuilder.setid (1); teavuilder.setname ("testtea"); Teabuilder.addallstudentlist (stubuilderlist); // Tulis GPB ke FileF FileOutputStream fos = FileOutputStream baru ("c: //users//shun//desktop//test//test.protoout"); teavuilder.build (). writeto (fos); fos.close (); }} </span> Mari kita lihat file, jika tidak ada yang tidak terduga terjadi, itu seharusnya dihasilkan.
Setelah dihasilkan, kita harus membacanya kembali.
paket com.shun.test; impor java.io.fileInputStream; impor java.io.filenotfoundException; impor java.io.ioException; impor com.shun.studentproto.student; impor com.shun.teacherproto.teacher; Public Class ProtoreAdtest {public static void main (string [] args) melempar filenotfoundException, ioException {guru guru = guru.parsefrom (FileInputStream baru ("c: //users/shun//desktop/test//test.protoout")); System.out.println ("ID Guru:" + Teacher.GetID () + ", Nama:" + Teacher.GetName ()); untuk (siswa Stu: Teacher.getStudentListList ()) {System.out.println ("ID Siswa:" + Stu.getId () + ", nama:" + stu.getname () + ", usia:" + stu.getage ()); }}}} </span> Kode ini sangat sederhana karena semua kode yang dihasilkan oleh GPB dilakukan untuk kita.
Di atas mengetahui penggunaan dasar. Kami akan fokus pada perbedaan antara ukuran file yang dihasilkan GPB dan JSON. Saya tidak akan memposting kode rinci JSON di sini. Saya akan memposting contoh nanti. Jika Anda tertarik, Anda dapat mengunduhnya.
Di sini kami menggunakan GSON untuk mengurai JSON. Berikut ini hanya kode untuk mengubah objek menjadi JSON dan menulis file:
Saya tidak akan menulis definisi dasar dari dua kelas siswa dan guru, lakukan saja seperti yang Anda suka, kodenya adalah sebagai berikut:
paket com.shun.test; impor java.io.filewriter; impor java.io.ioException; impor java.util.arraylist; impor java.util.list; impor com.google.gson.gson; impor com.shun.student; impor com.shun.teacher; kelas publik gsonwritetest {public static void main (string [] args) melempar ioException {student stu = new student (); Stu.setage (25); Stu.setid (22); Stu.setname ("Shun"); Daftar <Sahasiswa> stulist = new ArrayList <shongents> (); stulist.add (Stu); Guru guru = guru baru (); guru.setid (22); guru.setname ("shun"); guru.setstulist (stulist); Hasil string = GSON baru (). TOJSON (guru); FileWriter fw = FileWriter baru ("c: // pengguna // shun/desktop // test // json"); fw.write (hasil); fw.close (); }} </span> Selanjutnya, kami secara resmi memasukkan kode pengujian nyata kami. Pada awalnya, kami hanya memasukkan objek dalam daftar. Selanjutnya, kami menguji ukuran file yang dihasilkan oleh GPB dan JSON pada gilirannya.
Tingkatkan kode GPB sebelumnya, biarkan itu menghasilkan jumlah daftar yang berbeda dan meregenerasi file:
paket com.shun.test; impor java.io.fileoutputStream; impor java.io.ioException; impor java.util.arraylist; impor java.util.list; impor com.shun.studentproto.student; impor com.shun.teacherproto.teacher; Public Class ProtowRitetest {Ukuran int final statis publik = 100; public static void main (string [] args) melempar ioException {// daftar daftar daftar <sahen> stubuilderlist = new arraylist <schuid> (); untuk (int i = 0; i <size; i ++) {student.builder stubuilder = student.newBuilder (); stubuilder.setage (25); stubuilder.setid (11); stubuilder.setname ("shun"); stubuilderlist.add (stubuilder.build ()); } Teacher.Builder Teabuilder = Teacher.NewBuilder (); Teabuilder.setid (1); teavuilder.setname ("testtea"); Teabuilder.addallstudentlist (stubuilderlist); // Tulis GPB ke File FileOutputStream fos = new FileOutputStream ("c: // pengguna // shun // desktop // test // proto-" + size); teavuilder.build (). writeto (fos); fos.close (); }} </span> Ukuran di sini diubah ke nomor tes yang kami katakan di atas pada gilirannya, dan Anda bisa mendapatkan yang berikut:
Lalu mari kita lihat kode uji JSON:
paket com.shun.test; impor java.io.filewriter; impor java.io.ioException; impor java.util.arraylist; impor java.util.list; impor com.google.gson.gson; impor com.shun.student; impor com.shun.teacher; kelas publik gsonwritetest {public static final int size = 100; public static void main (string [] args) melempar ioException {list <shikent> stulist = new arraylist <schuid> (); untuk (int i = 0; i <size; i ++) {siswa Stu = siswa baru (); Stu.setage (25); Stu.setid (22); Stu.setname ("Shun"); stulist.add (Stu); } Guru guru = guru baru (); guru.setid (22); guru.setname ("shun"); guru.setstulist (stulist); Hasil string = GSON baru (). TOJSON (guru); FileWriter fw = FileWriter baru ("c: // pengguna // shun // desktop // test // json" + size); fw.write (hasil); fw.close (); }} </span> Metode yang sama digunakan untuk memodifikasi ukuran dan melakukan tes yang sesuai.
Dapat dilihat dengan jelas bahwa ukuran file JSON dan GPB akan memiliki perbedaan besar ketika volume data secara bertahap meningkat. JSON jelas jauh lebih besar.
Tabel di atas harus lebih jelas. GPB Big Data sangat dominan, tetapi secara umum, klien dan server tidak akan secara langsung berinteraksi dengan data besar seperti itu. Big Data terutama terjadi dalam transmisi server. Jika Anda menghadapi kebutuhan, Anda perlu mengirimkan ratusan file log ke server lain setiap hari, maka GPB di sini mungkin sangat membantu.
Dikatakan sebagai perbandingan kedalaman, tetapi perbandingan utamanya adalah ukurannya, dan perbandingan waktu tidak terlalu banyak, juga tidak ada banyak perbedaan.
Untuk parser GSON yang dipilih dalam artikel, teman -teman yang tertarik dapat memilih Jackson atau Fastjson, atau lainnya, tetapi ukuran file yang dihasilkannya sama, tetapi waktu penguraian berbeda.