Creo que todos saben qué es JSON. Si no lo sabes, realmente está fuera. GOOGLE. No presentaré nada aquí.
Supongo que todos rara vez escuchan sobre ProtoBuffer, pero si Google lo hace, creo que todos estarán interesados en probarlo. Después de todo, las exportaciones de Google son en su mayoría productos de alta calidad.
ProtoBuffer es un protocolo de transmisión similar al JSON. De hecho, no se puede decir que sea un protocolo, es solo una cosa de transmisión de datos.
Entonces, ¿cuál es la diferencia entre él y JSON?
Cross-lengua, esta es una de sus ventajas. Viene con un compilador, protocas, que solo necesita ser compilada con él, y puede compilarse en el código Java, Python y C ++. Solo hay estos tres por el momento, así que no piensen en los demás por el momento, y luego puede usarlos directamente sin escribir ningún otro código. Incluso los analizados ya vienen con ellos. JSON es, por supuesto, un idioma cruzado, pero este idioma cruzado se basa en el código de escritura.
Si quieres saber más, puedes verlo:
https://developers.google.com/protocol-buffers/docs/overview
De acuerdo, sin más preámbulos, echemos un vistazo a por qué necesitamos comparar ProtoBuffer (en adelante denominado GPB) y JSON.
1. Debido a que JSON tiene un cierto formato y existe en caracteres, todavía hay espacio para la compresión en la cantidad de datos. Cuando la cantidad de big data en GPB es mucho menor que la de JSON, podemos ver el ejemplo a continuación.
2. La diferencia de eficiencia entre las bibliotecas JSON es bastante grande, y hay una brecha de aproximadamente 5-10 entre las bibliotecas de Jackson y GSON (esto solo se ha probado una vez, si hay algún error, por favor, dale palmaditas). GPB solo necesita uno, y no hay diferencia entre las llamadas bibliotecas múltiples. Por supuesto, este punto está compuesto por los números, y se puede ignorar.
Hablar es barato, solo muéstrame el código.
En el mundo de la programación, el código es siempre el rey, así que vamos al código.
Antes de cargar el código, debe descargar primero el ProtoBuffer, aquí:
https://github.com/google/protobuf
1. En primer lugar, GPB debe tener un archivo con definiciones de clase similares, llamado un archivo Proto.
Tomemos el ejemplo de estudiantes y maestros para hacer un ejemplo:
Tenemos los siguientes dos archivos: student.proto
opción java_package = "com.shun"; opción java_outer_classname = "StudentProto"; Mensaje estudiante {requerido int32 id = 1; Nombre de cadena opcional = 2; INT32 opcional INT32 = 3; } </span> profesor.proto
importar "student.proto"; opción java_package = "com.shun"; opción java_outer_classname = "maestroproto"; maestro de mensajes {requerido int32 id = 1; Nombre de cadena opcional = 2; Estudiante de estudiante repetido_list = 3; } </span> Aquí encontramos algunas cosas extrañas:
importar, int32, repetido, requerido, opcional, opción, etc.
1) Importar significa importar otros archivos Proto
2) Requerido y opcional indica si el campo es opcional. Esto determina qué procesamiento realizará el ProtoBuffer si el campo tiene un valor o no. Si se requiere se marca, pero al procesar, el campo no pasa el valor, se informará un error; Si la opcional está marcada, no se transmitirá ningún valor, no habrá ningún problema.
3) Creo que puedes entender repetidos, lo que significa si se repite, es similar a la lista de Java.
4) El mensaje es equivalente a la clase
5) La opción representa la opción, donde Java_Package representa el nombre del paquete, es decir, el nombre del paquete utilizado al generar código Java. Java_outer_classname es el nombre de la clase. Tenga en cuenta que este nombre de clase no puede ser el mismo que el nombre de clase en el mensaje a continuación.
En cuanto a otras opciones y tipos relacionados, visite la documentación oficial.
2. Con estos documentos, ¿qué podemos hacer?
Recuerde el compilador descargado anteriormente. Descriptelo y obtenemos una protoc.exe. Por supuesto, esto se basa en Windows. No hice otros sistemas. Si está interesado, puede probarlo.
Agregar a la ruta (es fácil de agregar o no, es simplemente inconveniente), y luego puede generar el archivo de clase que necesitamos a través del archivo anterior.
Protoc --java_out = ruta para almacenar el código fuente --proto_path = ruta a proto archivo protoproppectriz archivo específico
--proto_path Especifica la ruta de la carpeta del archivo Proto, ni un solo archivo, se usa principalmente para la búsqueda de archivos de importación y se puede omitir
Si necesito poner el código fuente en D:/ProtoBuffervsjson/SRC, mi archivo Proto se almacena en D:/Protofiles
Entonces mi comando de compilación es:
Protoc --java_out = D:/ProtoBuffervsjson/src d: /protofiles/teacher.proto d: /protofiles/student.proto
Tenga en cuenta que en el último archivo aquí, necesitamos especificar todos los archivos que deben compilarse.
Después de la compilación, puede ver el archivo generado.
El código no está publicado, demasiado. Puedes mirar en privado. Hay muchos constructores en el código. Creo que sabrá que es el modo de constructor de un vistazo.
En este momento, puede pegar el código en su proyecto y, por supuesto, hay muchos errores.
¿Recuerdas el código fuente que descargamos anteriormente? Deséjelo, no seas despiadado. Luego busque src/main/java/para copiar uno de ellos a su proyecto. Por supuesto, también puedes compilar Ant o Maven, pero no estoy familiarizado con estas dos cosas, por lo que ya no seré feo. Todavía estoy acostumbrado a copiarlos directamente al proyecto.
El error del código, jaja, normal. Por alguna razón, Google insiste en dejar ese pozo para nosotros.
Regrese a /java en el directorio de ProtoBuffer y vea un readme.txt, y encuentre una oración:
Después de mirarlo, siento que este código será un poco extraño, como si estuviera mal. De todos modos, no lo ejecuté, y mi comando es:
<span style = "font-size: 16px;"> protoc --java_out = o la ruta del archivo proto donde se coloca el código (aquí está la ruta del archivo descriptor.proto) </span>
Después de la ejecución, podemos ver que no hay errores en el código.
3. El siguiente paso es, por supuesto, las pruebas.
Realicemos primero la prueba de escritura GPB:
paquete com.shun.test; import java.io.fileOutputStream; import java.io.ioException; import java.util.arrayList; import java.util.list; import com.shun.studentproto.student; import com.shun.teacherproto.teacher; Public Class ProtoWriteTest {public static void main (string [] args) lanza ioexception {student.builder stubuilder = student.newbuilder (); stubuilder.setage (25); stubuilder.setId (11); stubuilder.setName ("shun"); // Lista de construcción de la lista <Sentuent> stubuilderList = new ArrayList <Estudio> (); stubuilderList.add (stubuilder.build ()); Profesor.builder teaBuilder = maestro.newbuilder (); TeaBuilder.SetId (1); teabuilder.setName ("testtea"); TeaBuilder.addallStudentList (stubuilderList); // Escribe GPB para archivar FileOutputStream fos = new FileOutputStream ("c: //users//shun//desktop//test//test.protout"); teabuilder.build (). Writeto (FOS); fos.close (); }} </span> Veamos el archivo, si no sucede nada inesperado, debería haberse generado.
Después de generarlo, debemos leerlo.
paquete com.shun.test; import java.io.fileInputStream; import java.io.filenotfoundException; import java.io.ioException; import com.shun.studentproto.student; import com.shun.teacherproto.teacher; Public Class ProtoreadTest {public static void main (String [] args) lanza FileNotFoundException, ioexception {maestro maestro = maestro.parsefrom (nuevo fileinputstream ("c: //users//shun//desktop//test//test.protout"); System.out.println ("ID de maestro:" + maestro.getid () + ", nombre:" + maestro.getName ()); para (Student Stu: maestro.getStudentListList ()) {System.out.println ("estudiante id:" + stu.getid () + ", nombre:" + stu.getName () + ", edad:" + stu.getage ()); }}}} </span> El código es muy simple porque todo el código generado por GPB está hecho para nosotros.
Lo anterior conoce el uso básico. Nos centraremos en la diferencia entre los tamaños de archivo generados por GPB y JSON. No publicaré el código detallado de JSON aquí. Publicaré un ejemplo más tarde. Si está interesado, puede descargarlo.
Aquí usamos GSON para analizar JSON. El siguiente es solo el código para convertir el objeto en JSON y escribir el archivo:
No escribiré las definiciones básicas del estudiante y el maestro de las dos clases, solo hazlo como quieras, el código es el siguiente:
paquete com.shun.test; import java.io.filewriter; import java.io.ioException; import java.util.arrayList; import java.util.list; import com.google.gson.gson; import com.shun.student; import com.shun.Teacher; Public Class GsonWriteTest {public static void main (String [] args) lanza ioexception {estudiante stu = new student (); stu.setage (25); stu.setid (22); stu.setName ("shun"); List <druent> stulist = new ArrayList <Enstude> (); stulist.add (stu); Maestro maestro = nuevo maestro (); profesor.setid (22); maestro.setName ("shun"); profesor.setstulist (estulista); Resultado de cadena = new Gson (). TJson (maestro); FileWriter fw = new FileWriter ("c: // users // shun/escritorio // test // json"); fw.write (resultado); fw.close (); }} </span> A continuación, ingresamos oficialmente nuestro código de prueba real. Al principio, solo ponemos un objeto en la lista. A continuación, probamos los tamaños de archivo generados por GPB y JSON a su vez.
Mejore el código GPB anterior, permita que genere un número diferente de listas y regenere archivos:
paquete com.shun.test; import java.io.fileOutputStream; import java.io.ioException; import java.util.arrayList; import java.util.list; import com.shun.studentproto.student; import com.shun.teacherproto.teacher; clase pública ProtoWritETest {public static static final int size = 100; public static void main (string [] args) lanza IoException {// Lista de construcción Lista <Sentuend> stubuilderList = new ArrayList <Sentuent> (); for (int i = 0; i <size; i ++) {student.builder stubuilder = student.newBuilder (); stubuilder.setage (25); stubuilder.setId (11); stubuilder.setName ("shun"); stubuilderList.add (stubuilder.build ()); } Profesor.builder teaBuilder = maestro.newBuilder (); TeaBuilder.SetId (1); teabuilder.setName ("testtea"); TeaBuilder.addallStudentList (stubuilderList); // Escribe GPB para archivar FileOutputStream Fos = new FileOutputStream ("c: // users // shun // escritorio // test // proto-" + size); teabuilder.build (). Writeto (FOS); fos.close (); }} </span> El tamaño aquí se cambia al número de prueba que dijimos anteriormente a su vez, y puede obtener lo siguiente:
Luego echemos un vistazo al código de prueba JSON:
paquete com.shun.test; import java.io.filewriter; import java.io.ioException; import java.util.arrayList; import java.util.list; import com.google.gson.gson; import com.shun.student; import com.shun.Teacher; clase pública GSONWriteTest {public static static final int size = 100; public static void main (string [] args) lanza ioexception {list <diest> stulist = new ArrayList <Sentuent> (); para (int i = 0; i <size; i ++) {Student stu = new Student (); stu.setage (25); stu.setid (22); stu.setName ("shun"); stulist.add (stu); } Maestro maestro = nuevo maestro (); profesor.setid (22); maestro.setName ("shun"); profesor.setstulist (estulista); Resultado de cadena = new Gson (). TJson (maestro); FileWriter fw = nuevo FileWriter ("c: // users // shun // escritorio // test // json" + size); fw.write (resultado); fw.close (); }} </span> El mismo método se utiliza para modificar el tamaño y realizar las pruebas correspondientes.
Se puede ver claramente que el tamaño del archivo de JSON y GPB tendrá una gran diferencia cuando el volumen de datos aumente gradualmente. JSON es obviamente mucho más grande.
La tabla de arriba debe ser más clara. GPB de Big Data es muy dominante, pero en general, el cliente y el servidor no interactuarán directamente con dichos big data. Big Data ocurre principalmente en la transmisión del servidor. Si se enfrenta a las necesidades, debe transmitir cientos de m de archivos de registro a otro servidor todos los días, entonces el GPB aquí puede ser de gran ayuda.
Se dice que es una comparación de profundidad, pero la comparación principal es el tamaño, y la comparación de tiempo no es demasiado, ni hay mucha diferencia.
Para el analizador GSON seleccionado en el artículo, los amigos interesados pueden elegir Jackson o Fastjson, u otro, pero el tamaño del archivo generado es el mismo, pero el tiempo de análisis es diferente.