最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Java實(shí)現(xiàn)Avro文件讀寫功能

 更新時(shí)間:2022年02月18日 09:37:45   作者:BigDataToAI  
大家好,本篇文章主要講的是基于Java實(shí)現(xiàn)Avro文件讀寫功能,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下

Apache Avro是一個(gè)數(shù)據(jù)序列化系統(tǒng)。具有如下基本特性:

豐富的數(shù)據(jù)結(jié)構(gòu)。一種緊湊、快速的二進(jìn)制數(shù)據(jù)格式。一個(gè)容器文件,用于存儲(chǔ)持久數(shù)據(jù)。遠(yuǎn)程過(guò)程調(diào)用 (RPC)。與動(dòng)態(tài)語(yǔ)言的簡(jiǎn)單集成。 代碼生成不需要讀取或?qū)懭霐?shù)據(jù)文件,也不需要使用或?qū)崿F(xiàn) RPC 協(xié)議。 代碼生成作為一種可選的優(yōu)化,只值得為靜態(tài)類型語(yǔ)言實(shí)現(xiàn)。

模式(schema)

Avro 依賴于模式。讀取 Avro 數(shù)據(jù)時(shí),寫入時(shí)使用的模式始終存在。 這允許在沒(méi)有每個(gè)值開(kāi)銷的情況下寫入每個(gè)數(shù)據(jù),從而使序列化既快速又小。 這也便于使用動(dòng)態(tài)腳本語(yǔ)言,因?yàn)閿?shù)據(jù)及其模式是完全自描述的。

當(dāng) Avro 數(shù)據(jù)存儲(chǔ)在文件中時(shí),它的模式也隨之存儲(chǔ),以便以后任何程序都可以處理文件。 如果讀取數(shù)據(jù)的程序需要不同的模式,這很容易解決,因?yàn)閮煞N模式都存在。

在 RPC 中使用 Avro 時(shí),客戶端和服務(wù)器在連接握手中交換模式。 (這可以優(yōu)化,使得對(duì)于大多數(shù)調(diào)用,實(shí)際上不傳輸模式。)由于客戶端和服務(wù)器都具有對(duì)方的完整模式,因此可以輕松解決相同命名字段之間的對(duì)應(yīng)關(guān)系,如缺少字段,額外字段等 .

Avro 模式是用 JSON 定義的。 這有助于在已經(jīng)具有 JSON 庫(kù)的語(yǔ)言中實(shí)現(xiàn)。

與其他系統(tǒng)的比較

Avro 提供類似于 Thrift、Protocol Buffers 等系統(tǒng)的功能。Avro 在以下基本方面與這些系統(tǒng)不同。

動(dòng)態(tài)類型:Avro 不需要生成代碼。 數(shù)據(jù)總是伴隨著一個(gè)模式,該模式允許在沒(méi)有代碼生成、靜態(tài)數(shù)據(jù)類型等的情況下完全處理該數(shù)據(jù)。這有助于構(gòu)建通用數(shù)據(jù)處理系統(tǒng)和語(yǔ)言。未標(biāo)記數(shù)據(jù):由于在讀取數(shù)據(jù)時(shí)存在模式,因此需要用數(shù)據(jù)編碼的類型信息要少得多,從而導(dǎo)致更小的序列化大小。沒(méi)有手動(dòng)分配的字段 ID:當(dāng)架構(gòu)更改時(shí),處理數(shù)據(jù)時(shí)始終存在舊架構(gòu)和新架構(gòu),因此可以使用字段名稱象征性地解決差異。

Java客戶端實(shí)現(xiàn)

以下代碼基于maven項(xiàng)目實(shí)現(xiàn)Java讀寫Avro

首先在maven項(xiàng)目中添加下述依賴:

<dependency>
  <groupId>org.apache.avro</groupId>
  <artifactId>avro</artifactId>
  <version>1.11.0</version>
</dependency>

以及下述插件

<plugin>
  <groupId>org.apache.avro</groupId>
  <artifactId>avro-maven-plugin</artifactId>
  <version>1.11.0</version>
  <executions>
    <execution>
      <phase>generate-sources</phase>
      <goals>
        <goal>schema</goal>
      </goals>
      <configuration>
        <sourceDirectory>${project.basedir}/src/main/avro/</sourceDirectory>
        <outputDirectory>${project.basedir}/src/main/java/</outputDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <configuration>
    <source>1.8</source>
    <target>1.8</target>
  </configuration>
</plugin>

定義一個(gè)schema

Avro 模式是使用 JSON 定義的。 模式由基本類型(null、boolean、int、long、float、double、bytes 和 string)和復(fù)雜類型(record、enum、array、map、union 和 fixed)組成。 您可以從規(guī)范中了解有關(guān) Avro 模式和類型的更多信息,但現(xiàn)在讓我們從一個(gè)簡(jiǎn)單的模式示例 user.avsc 開(kāi)始:

{
  "namespace": "com.bigdatatoai.avro.generate",
  "type": "record",
  "name": "User",
  "fields": [
    {
      "name": "name",
      "type": "string"
    },
    {
      "name": "favorite_number",
      "type": [
        "int",
        "null"
      ]
    },
    {
      "name": "favorite_color",
      "type": [
        "string",
        "null"
      ]
    }
  ]
}

此模式定義了代表假設(shè)用戶的記錄。 (請(qǐng)注意,模式文件只能包含單個(gè)模式定義。)記錄定義至少必須包括其類型(“type”:“record”)、名稱(“name”:“User”)和字段, 在本例中為 name、favorite_number 和 favorite_color。 我們還定義了一個(gè)命名空間(“namespace”:“com.bigdatatoai.avro.generate”),它與 name 屬性一起定義了模式的“全名”(在本例中為 com.bigdatatoai.avro.User)。

字段是通過(guò)對(duì)象數(shù)組定義的,每個(gè)對(duì)象都定義了一個(gè)名稱和類型(其他屬性是可選的,有關(guān)詳細(xì)信息,請(qǐng)參閱記錄規(guī)范)。 字段的類型屬性是另一個(gè)模式對(duì)象,它可以是基本類型或復(fù)雜類型。 例如,我們的 User 模式的 name 字段是原始類型字符串,而 favorite_number 和 favorite_color 字段都是聯(lián)合,由 JSON 數(shù)組表示。 unions 是一種復(fù)雜類型,可以是數(shù)組中列出的任何類型; 例如, favorite_number 可以是 int 或 null,本質(zhì)上使它成為一個(gè)可選字段。

使用Java代碼生成插件生成的User類進(jìn)行序列化和反序列化

已知我們?cè)趍aven項(xiàng)目中添加了avro插件,那么我們便可以使用compile命令生成User類。

下述以IDEA為例

現(xiàn)在我們已經(jīng)完成了代碼生成,讓我們創(chuàng)建一些用戶,將它們序列化為磁盤上的數(shù)據(jù)文件,然后讀回文件并反序列化用戶對(duì)象。

創(chuàng)建User用戶

        // 新建user三種方式
        // 方式1
        User user1 = new User();
        user1.setName("Alyssa");
        user1.setFavoriteNumber(256);
        // 方式2
        User user2 = new User("Ben", 7, "red");
        // 方式3
        User user3 = User.newBuilder()
                .setName("Charlie")
                .setFavoriteColor("blue")
                .setFavoriteNumber(null)
                .build();

如本例所示,可以通過(guò)直接調(diào)用構(gòu)造函數(shù)或使用構(gòu)建器來(lái)創(chuàng)建 Avro 對(duì)象。 與構(gòu)造函數(shù)不同,生成器將自動(dòng)設(shè)置模式中指定的任何默認(rèn)值。 此外,構(gòu)建器會(huì)按設(shè)置驗(yàn)證數(shù)據(jù),而直接構(gòu)造的對(duì)象在對(duì)象被序列化之前不會(huì)導(dǎo)致錯(cuò)誤。 但是,直接使用構(gòu)造函數(shù)通常會(huì)提供更好的性能,因?yàn)闃?gòu)造函數(shù)會(huì)在寫入數(shù)據(jù)結(jié)構(gòu)之前創(chuàng)建數(shù)據(jù)結(jié)構(gòu)的副本。

請(qǐng)注意,我們沒(méi)有設(shè)置 user1 最喜歡的顏色。 由于該記錄的類型為 [“string”, “null”],我們可以將其設(shè)置為字符串或?qū)⑵浔A魹?null; 它本質(zhì)上是可選的。 同樣,我們將 user3 最喜歡的數(shù)字設(shè)置為 null(使用構(gòu)建器需要設(shè)置所有字段,即使它們?yōu)?null)。

將上述新建的User用戶序列化并保存到磁盤

        // 持久化數(shù)據(jù)到磁盤
        DatumWriter<User> userDatumWriter = new SpecificDatumWriter<User>(User.class);
        DataFileWriter<User> dataFileWriter = new DataFileWriter<User>(userDatumWriter);
        dataFileWriter.create(user1.getSchema(), new File("users.avro"));
        dataFileWriter.append(user1);
        dataFileWriter.append(user2);
        dataFileWriter.append(user3);
        dataFileWriter.close();

從磁盤讀取users.avro并反序列化輸出

        // 從User反序列化數(shù)據(jù)
        DatumReader<User> userDatumReader = new SpecificDatumReader<User>(User.class);
        DataFileReader<User> dataFileReader = new DataFileReader<User>(new File("users.avro"), userDatumReader);
        User user = null;
        while (dataFileReader.hasNext()) {
            user = dataFileReader.next(user);
            System.out.println(user);
        }

在不生成User類的情況下直接進(jìn)行序列化和反序列化操作

Avro 中的數(shù)據(jù)始終與其對(duì)應(yīng)的模式一起存儲(chǔ),這意味著無(wú)論我們是否提前知道模式,我們都可以隨時(shí)讀取序列化項(xiàng)目。 這允許我們?cè)诓簧纱a的情況下執(zhí)行序列化和反序列化。

讓我們回顧與上一節(jié)相同的示例,但不使用代碼生成:我們將創(chuàng)建一些用戶,將它們序列化為磁盤上的數(shù)據(jù)文件,然后讀回文件并反序列化用戶對(duì)象。

使用user.avsc文件創(chuàng)建User用戶

        Schema schema = new Schema.Parser().parse(new File("java-example/src/main/avro/com/bigdatatoai/avro/user.avsc"));
        GenericRecord user1 = new GenericData.Record(schema);
        user1.put("name", "Alyssa");
        user1.put("favorite_number", 256);

        GenericRecord user2 = new GenericData.Record(schema);
        user2.put("name", "Ben");
        user2.put("favorite_number", 7);
        user2.put("favorite_color", "red");

由于我們不使用代碼生成,我們使用 GenericRecords 來(lái)表示用戶。 GenericRecord 使用模式來(lái)驗(yàn)證我們是否只指定了有效字段。 如果我們嘗試設(shè)置一個(gè)不存在的字段(例如,user1.put(“favorite_animal”, “cat”)),我們將在運(yùn)行程序時(shí)收到 AvroRuntimeException。

請(qǐng)注意,我們沒(méi)有設(shè)置 user1 最喜歡的顏色。 由于該記錄的類型為 [“string”, “null”],我們可以將其設(shè)置為字符串或?qū)⑵浔A魹?null; 它本質(zhì)上是可選的。

將上述新建的User持久化到磁盤

        File file = new File("users2.avro");
        DatumWriter<GenericRecord> datumWriter = new GenericDatumWriter<GenericRecord>(schema);
        DataFileWriter<GenericRecord> dataFileWriter = new DataFileWriter<GenericRecord>(datumWriter);
        dataFileWriter.create(schema, file);
        dataFileWriter.append(user1);
        dataFileWriter.append(user2);
        dataFileWriter.close();

從磁盤讀取users.avro并反序列化輸出

        DatumReader<GenericRecord> datumReader = new GenericDatumReader<GenericRecord>(schema);
        DataFileReader<GenericRecord> dataFileReader = new DataFileReader<GenericRecord>(file, datumReader);
        GenericRecord user = null;
        while (dataFileReader.hasNext()) {
            user = dataFileReader.next(user);
            System.out.println(user);
        }

總結(jié)

到此這篇關(guān)于基于Java實(shí)現(xiàn)Avro文件讀寫功能的文章就介紹到這了,更多相關(guān)Java Avro讀寫功能內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java實(shí)現(xiàn)FIFO任務(wù)調(diào)度隊(duì)列策略

    Java實(shí)現(xiàn)FIFO任務(wù)調(diào)度隊(duì)列策略

    在工作中,很多高并發(fā)的場(chǎng)景中,我們會(huì)用到隊(duì)列來(lái)實(shí)現(xiàn)大量的任務(wù)請(qǐng)求。當(dāng)任務(wù)需要某些特殊資源的時(shí)候,我們還需要合理的分配資源,讓隊(duì)列中的任務(wù)高效且有序完成任務(wù)。本文將為大家介紹通過(guò)java實(shí)現(xiàn)FIFO任務(wù)調(diào)度,需要的可以參考一下
    2021-12-12
  • Java Socket設(shè)置timeout的幾種常用方式說(shuō)明

    Java Socket設(shè)置timeout的幾種常用方式說(shuō)明

    這篇文章主要介紹了Java Socket設(shè)置timeout的幾種常用方式說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • Spring MVC 基于URL的映射規(guī)則(注解版)

    Spring MVC 基于URL的映射規(guī)則(注解版)

    這篇文章主要介紹了Spring MVC 基于URL的映射規(guī)則(注解版) ,詳細(xì)的介紹了幾種方式,有興趣的可以了解一下
    2017-05-05
  • java集合進(jìn)行排序的方式總結(jié)

    java集合進(jìn)行排序的方式總結(jié)

    在本篇文章里小編給大家整理的是一篇關(guān)于java集合進(jìn)行排序的兩種方式總結(jié),有興趣的朋友們可以學(xué)習(xí)參考下。
    2021-08-08
  • Spring中DAO被循環(huán)調(diào)用的時(shí)候數(shù)據(jù)不實(shí)時(shí)更新的解決方法

    Spring中DAO被循環(huán)調(diào)用的時(shí)候數(shù)據(jù)不實(shí)時(shí)更新的解決方法

    這篇文章主要介紹了Spring中DAO被循環(huán)調(diào)用的時(shí)候數(shù)據(jù)不實(shí)時(shí)更新的解決方法,需要的朋友可以參考下
    2014-08-08
  • Java使用itextpdf找出PDF中文字的坐標(biāo)

    Java使用itextpdf找出PDF中文字的坐標(biāo)

    這篇文章主要為大家詳細(xì)介紹了Java如果使用itextpdf找出PDF中文字的坐標(biāo),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-01-01
  • idea設(shè)置JVM運(yùn)行參數(shù)的幾種方式

    idea設(shè)置JVM運(yùn)行參數(shù)的幾種方式

    對(duì)JVM運(yùn)行參數(shù)進(jìn)行修改是JVM性能調(diào)優(yōu)的重要手段,本文主要介紹了idea設(shè)置JVM運(yùn)行參數(shù)的幾種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • JDK8配置環(huán)境變量的bat文件的詳細(xì)教程

    JDK8配置環(huán)境變量的bat文件的詳細(xì)教程

    這篇文章主要介紹了JDK8配置環(huán)境變量的bat文件,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • mybatis-plus主鍵策略生成失敗的解決

    mybatis-plus主鍵策略生成失敗的解決

    本文主要介紹了mybatis-plus主鍵策略生成失敗的解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • Java不帶break將導(dǎo)致case穿透問(wèn)題

    Java不帶break將導(dǎo)致case穿透問(wèn)題

    這篇文章主要介紹了Java不帶break將導(dǎo)致case穿透問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-02-02

最新評(píng)論

阳曲县| 广水市| 曲麻莱县| 台南县| 伊宁市| 南平市| 洪湖市| 北安市| 普陀区| 安徽省| 玉山县| 茌平县| 万宁市| 桐梓县| 明星| 华宁县| 郓城县| 信阳市| 莱西市| 灯塔市| 察雅县| 崇礼县| 宣汉县| 合山市| 车险| 侯马市| 荔浦县| 通榆县| 洪湖市| 龙州县| 聂荣县| 沽源县| 丹阳市| 新乡市| 阳谷县| 蒲江县| 天祝| 孟村| 安岳县| 福州市| 来安县|