SpringBatch文件读写ItemWriter,ItemReader使用详解

SpringBatch文件读写ItemWriter,ItemReader使用详解

  • 1. ItemReaders 和 ItemWriters
    • 1.1. ItemReader
    • 1.2. ItemWriter
    • 1.3. ItemProcessor
  • 2.FlatFileItemReader 和 FlatFileItemWriter
    • 2.1.平面文件
      • 2.1.1. FieldSet
    • 2.2. FlatFileItemReader
    • 2.3. FlatFileItemWriter
  • 3.FlatFileItemReader 和 FlatFileItemWriter 使用案例

1. ItemReaders 和 ItemWriters

所有批处理都可以以其最简单的形式描述为读取大量数据,执行某种类型的计算或转换并写出结果。 Spring Batch 提供了三个关键接口来帮助执行批量读取和写入:ItemReader,ItemProcessor 和 ItemWriter。

1.1. ItemReader

注:内容来源于springbatch官网: https://docs.spring.io/spring-batch/reference/readers-and-writers/item-reader.html

尽管是一个简单的概念,但ItemReader是用于从许多不同类型的 Importing 中提供数据的方法。最一般的示例包括:

  • 平面文件:平面文件 Item 读取器从平面文件中读取数据行,该文件通常描述记录,这些记录的数据字段由文件中的固定位置定义或由某些特殊字符(例如逗号)分隔。

  • XML:XML ItemReaders独立于用于解析,Map 和验证对象的技术来处理 XML。Importing 数据允许根据 XSD 模式验证 XML 文件。

  • 数据库:访问数据库资源以返回结果集,该结果集可以 Map 到对象以进行处理。默认的 SQL ItemReader实现调用RowMapper来返回对象,如果需要重新启动,则跟踪当前行,存储基本统计信息,并提供一些事务增强功能,这些将在后面进行说明。

ItemReader是通用 Importing 操作的基本接口,如以下接口定义所示:

public interface ItemReader<T> {
    T read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException;
}

read方法定义ItemReader的最基本 Contract。调用它会返回一个 Item;如果没有更多 Item,则返回null。一个 Item 可能代表文件中的一行,数据库中的一行或 XML 文件中的元素。通常希望将它们 Map 到可用的域对象(例如Trade,Foo或其他),但是 Contract 中没有要求这样做。

1.2. ItemWriter

ItemWriter在功能上与ItemReader类似,但是具有相反的运算。资源仍然需要定位,打开和关闭,但是它们的区别在于ItemWriter是写出而不是读入。对于数据库或队列,这些操作可能是插入,更新或发送。输出序列化的格式特定于每个批处理作业。

与ItemReader一样,ItemWriter是一个相当通用的接口,如以下接口定义所示:

public interface ItemWriter<T> {
    void write(List<? extends T> items) throws Exception;
}

与ItemReader上的read一样,write提供ItemWriter的基本 Contract。只要打开,它就会尝试写出传入 Item 的列表。因为通常期望将 Item“分批”在一起,然后输出,所以接口接受 Item 列表,而不是 Item 本身。写入列表后,可以执行任何必要的刷新操作,然后再从 write 方法返回。例如,如果写入一个 Hibernate DAO,则可以进行多个写入操作,每个 Item 一个。然后,Writer 可以在休眠会话上调用flush,然后再返回。

1.3. ItemProcessor

ItemReader和ItemWriter接口对于它们的特定任务都非常有用,但是如果要在编写之前插入业务逻辑怎么办?读写的一种选择是使用复合模式:创建包含另一个ItemWriter的ItemWriter或包含另一个ItemReader的ItemReader。以下代码显示了一个示例:

public class CompositeItemWriter<T> implements ItemWriter<T> {

    ItemWriter<T> itemWriter;

    public CompositeItemWriter(ItemWriter<T> itemWriter) {
        this.itemWriter = itemWriter;
    }

    public void write(List<? extends T> items) throws Exception {
        //Add business logic here
       itemWriter.write(items);
    }

    public void setDelegate(ItemWriter<T> itemWriter){
        this.itemWriter = itemWriter;
    }
}

上一类包含另一个ItemWriter,它在提供了一些业务逻辑后将其委托给该ItemWriter。该模式也可以很容易地用于ItemReader,也许可以基于主ItemReader提供的 Importing 来获取更多参考数据。如果您需要自己控制对write的调用,它也很有用。但是,如果您只想在实际写入之前“转换”传递给写入的 Item,则无需自己write。您可以只修改 Item。对于这种情况,Spring Batch 提供了ItemProcessor接口,如以下接口定义所示:

public interface ItemProcessor<I, O> {

    O process(I item) throws Exception;
}

ItemProcessor很简单。给定一个对象,对其进行转换,然后返回另一个。提供的对象可以是或可以不是相同的类型。关键是可以在流程中应用业务逻辑,并且完全由开发人员来创建该逻辑。 ItemProcessor可以直接连接到步骤中。例如,假设ItemReader提供了Foo类型的类,并且在将其写出之前需要将其转换为Bar类型。以下示例显示了执行转换的ItemProcessor:

public class Foo {}

public class Bar {
    public Bar(Foo foo) {}
}

public class FooProcessor implements ItemProcessor<Foo,Bar>{
    public Bar process(Foo foo) throws Exception {
        //Perform simple transformation, convert a Foo to a Bar
        return new Bar(foo);
    }
}

public class BarWriter implements ItemWriter<Bar>{
    public void write(List<? extends Bar> bars) throws Exception {
        //write bars
    }
}

在前面的示例中,存在一个类Foo,一个类Bar和一个FooProcessor,它们坚持ItemProcessor接口。转换很简单,但是任何类型的转换都可以在这里完成。 BarWriter写入Bar对象,如果提供任何其他类型,则抛出异常。同样,如果提供了Foo以外的内容,则FooProcessor引发异常。然后可以将FooProcessor注入到Step中,如以下示例所示:

@Bean
public Job ioSampleJob() {
        return this.jobBuilderFactory.get("ioSampleJOb")
                                .start(step1())
                                .end()
                                .build();
}

@Bean
public Step step1() {
        return this.stepBuilderFactory.get("step1")
                                .<String, String>chunk(2)
                                .reader(fooReader())
                                .processor(fooProcessor())
                                .writer(barWriter())
                                .build();
}

2.FlatFileItemReader 和 FlatFileItemWriter

注:内容来源springbatch官网链接: https://docs.spring.io/spring-batch/reference/readers-and-writers/flat-files/field-set.html

2.1.平面文件

交换批量数据的最常见机制之一一直是平面文件。与 XML 具有定义其结构化(XSD)的公认标准不同,任何阅读平面文件的人都必须提前了解文件的结构。通常,所有平面文件都分为两种:定界文件和定长文件。分隔文件是指用逗号分隔分隔符的字段。固定长度文件具有设置长度的字段。

2.1.1. FieldSet

在 Spring Batch 中使用平面文件时,无论是用于 Importing 还是输出,最重要的类之一是FieldSet。许多体系结构和库都包含用于帮助您从文件读入的抽象,但是它们通常返回String或String对象的数组。这真的只会让您半途而废。 FieldSet是 Spring Batch 的抽象,用于启用文件资源中字段的绑定。它使开发人员可以像处理数据库 Importing 一样使用文件 Importing。 FieldSet在概念上与 JDBC ResultSet类似。 FieldSet仅需要一个参数:String令牌数组。 (可选)您还可以配置字段的名称,以便可以按ResultSet之后的模式通过索引或名称来访问字段,如以下示例所示:

String[] tokens = new String[]{"foo", "1", "true"};
FieldSet fs = new DefaultFieldSet(tokens);
String name = fs.readString(0);
int value = fs.readInt(1);
boolean booleanValue = fs.readBoolean(2);

FieldSet界面上还有更多选项,例如Date,long,BigDecimal等等。 FieldSet的最大优点是它提供了平面文件 Importing 的一致解析。在处理由格式异常引起的错误或进行简单的数据转换时,它可以保持一致,而不是使每个批处理作业以潜在的意外方式进行不同的解析。

2.2. FlatFileItemReader

平面文件是最多包含二维(表格)数据的任何类型的文件。名为FlatFileItemReader的类有助于在 Spring Batch 框架中读取平面文件,该类提供了用于读取和解析平面文件的基本功能。 FlatFileItemReader的两个最重要的必需依存关系是Resource和LineMapper。 LineMapper接口将在下一部分中进行详细介绍。 resource 属性表示一个 Spring Core Resource。可以在Spring 框架资源中找到说明如何创建此类 bean 的文档。

Resource resource = new FileSystemResource("resources/trades.csv");

FlatFileItemReader中的其他属性使您可以进一步指定数据的解释方式,如下表所述:

在这里插入图片描述
LineMapper
与RowMapper一样,它采用诸如ResultSet之类的低级构造并返回Object,平面文件处理需要相同的构造才能将String行转换为Object,如以下接口定义所示:

public interface LineMapper<T> {
    T mapLine(String line, int lineNumber) throws Exception;
}

基本约定是,给定当前行及其关联的行号,Map 器应返回结果域对象。这类似于RowMapper,因为每一行都与其行号相关联,就像ResultSet中的每一行都与其行号绑定一样。这允许将行号绑定到结果域对象,以进行身份比较或提供更多信息。但是,与RowMapper不同,LineMapper被赋予了原始行,如上所述,该原始行只会使您到达中间。该行必须标记为FieldSet,然后可以将其 Map 到一个对象

LineTokenizer
必须将 Importing 行转换为FieldSet的抽象,因为可能需要将多种格式的平面文件数据转换为FieldSet。在 Spring Batch 中,此接口是LineTokenizer:

public interface LineTokenizer {
    FieldSet tokenize(String line);
}

LineTokenizer的约定是这样的:给定 Importing 行(理论上String可以包含多条线),则返回代表该行的FieldSet。然后可以将此FieldSet传递给FieldSetMapper。 Spring Batch 包含以下LineTokenizer实现:

  • DelimitedLineTokenizer:用于 Logging 的字段由定界符分隔的文件。最常见的定界符是逗号,但是也经常使用竖线或分号。

  • FixedLengthTokenizer:用于 Logging 的字段均为“固定宽度”的文件。必须为每种记录类型定义每个字段的宽度。

  • PatternMatchingCompositeLineTokenizer:通过检查模式,确定应在特定行上使用标记器列表中的哪个LineTokenizer。

- FieldSetMapper
FieldSetMapper接口定义单个方法mapFieldSet,该方法采用FieldSet对象并将其内容 Map 到对象。根据作业的需要,此对象可以是自定义 DTO,域对象或数组。 FieldSetMapper与LineTokenizer结合使用,可将一行数据从资源转换为所需类型的对象,如以下接口定义所示:

public interface FieldSetMapper<T> {
    T mapFieldSet(FieldSet fieldSet) throws BindException;
}

使用的模式与JdbcTemplate使用的RowMapper相同。

DefaultLineMapper
既然已经定义了读取平面文件的基本接口,那么很明显,需要三个基本步骤:

  • 从文件中读取一行。
  • 将String行传递到LineTokenizer#tokenize()方法中以检索FieldSet。
  • 将标记化返回的FieldSet传递给FieldSetMapper,并从ItemReader#read()方法返回结果。

上述两个接口代表两个单独的任务:将线转换为FieldSet并将FieldSetMap 到域对象。因为LineTokenizer的 Importing 与LineMapper的 Importing(一条线)匹配,并且FieldSetMapper的输出与LineMapper的输出匹配,所以提供了同时使用LineTokenizer和FieldSetMapper的默认实现。下列类定义中显示的DefaultLineMapper表示大多数用户需要的行为:

public class DefaultLineMapper<T> implements LineMapper<>, InitializingBean {

    private LineTokenizer tokenizer;

    private FieldSetMapper<T> fieldSetMapper;

    public T mapLine(String line, int lineNumber) throws Exception {
        return fieldSetMapper.mapFieldSet(tokenizer.tokenize(line));
    }

    public void setLineTokenizer(LineTokenizer tokenizer) {
        this.tokenizer = tokenizer;
    }

    public void setFieldSetMapper(FieldSetMapper<T> fieldSetMapper) {
        this.fieldSetMapper = fieldSetMapper;
    }
}

以上功能是默认实现中提供的,而不是内置于 Reader 本身中(如在框架的先前版本中所做的那样),以使用户在控制解析过程时具有更大的灵 Active,尤其是在需要访问原始行的情况下。

2.3. FlatFileItemWriter

写入平面文件具有相同的问题和必须从文件中读取的问题。步骤必须能够以事务方式编写定界或定长格式。

LineAggregator
就像需要LineTokenizer接口来获取一项并将其变成String一样,文件写入必须具有一种将多个字段聚合到单个字符串中以写入文件的方法。在 Spring Batch 中,这是LineAggregator,如以下接口定义所示:

public interface LineAggregator<T> {
    public String aggregate(T item);
}

LineAggregator与LineTokenizer逻辑相反。 LineTokenizer取String并返回FieldSet,而LineAggregator取item并返回String。

PassThroughLineAggregator
LineAggregator接口的最基本实现是PassThroughLineAggregator,它假定对象已经是一个字符串或它的字符串表示形式可以接受写入,如以下代码所示:

public class PassThroughLineAggregator<T> implements LineAggregator<T> {
    public String aggregate(T item) {
        return item.toString();
    }
}

如果需要直接控制创建字符串,但是FlatFileItemWriter的优点(例如事务和重新启动支持)是必需的,则上述实现很有用。

简化文件编写示例
既然已经定义了LineAggregator接口及其最基本的实现PassThroughLineAggregator,那么可以说明基本的编写流程:

  • 要写入的对象被传递到LineAggregator以获得String。
  • 返回的String将被写入配置的文件。

FlatFileItemWriter的以下摘录用代码表示:

public void write(T item) throws Exception {
    write(lineAggregator.aggregate(item) + LINE_SEPARATOR);
}

一个简单的配置可能如下所示:

@Bean
public FlatFileItemWriter itemWriter() {
        return  new FlatFileItemWriterBuilder<Foo>()
                                   .name("itemWriter")
                                   .resource(new FileSystemResource("target/test-outputs/output.txt"))
                                   .lineAggregator(new PassThroughLineAggregator<>())
                                   .build();
}

FieldExtractor
前面的示例对于写入文件的最基本用途可能很有用。但是,FlatFileItemWriter的大多数用户都有一个域对象,需要将该域对象写出,因此必须将其转换为一行。在读取文件时,需要满足以下条件:

  • 从文件中读取一行。
  • 将行传递到LineTokenizer#tokenize()方法中,以便检索FieldSet。
    将标记化返回的FieldSet传递给FieldSetMapper,并从ItemReader#read()方法返回结果。

文件写入具有相似但相反的步骤:

  • 将要写入的 Item 传递给 Writer。
  • 将 Item 上的字段转换为数组。
  • 将结果数组聚合为一行。

因为框架没有办法知道需要写出对象中的哪些字段,所以必须写一个FieldExtractor来完成将 Item 变成数组的任务,如以下接口定义所示:

public interface FieldExtractor<T> {
    Object[] extract(T item);
}

FieldExtractor接口的实现应从提供的对象的字段中创建一个数组,然后可以使用元素之间的分隔符将其写出,也可以将其写为固定宽度的行的一部分。

PassThroughFieldExtractor
在许多情况下,需要写出集合,例如数组Collection或FieldSet。从这些集合类型之一中“提取”数组非常简单。为此,请将集合转换为数组。因此,在这种情况下应使用PassThroughFieldExtractor。应当注意,如果传入的对象不是集合的类型,则PassThroughFieldExtractor返回仅包含要提取的 Item 的数组。

BeanWrapperFieldExtractor
与在文件读取部分中介绍的BeanWrapperFieldSetMapper一样,通常最好配置如何将域对象转换为对象数组,而不是自己编写转换。 BeanWrapperFieldExtractor提供了此功能,如以下示例所示:

BeanWrapperFieldExtractor<Name> extractor = new BeanWrapperFieldExtractor<Name>();
extractor.setNames(new String[] { "first", "last", "born" });

String first = "Alan";
String last = "Turing";
int born = 1912;

Name n = new Name(first, last, born);
Object[] values = extractor.extract(n);

assertEquals(first, values[0]);
assertEquals(last, values[1]);
assertEquals(born, values[2]);

此提取器实现只有一个必需的属性:要 Map 的字段的名称。就像BeanWrapperFieldSetMapper需要字段名称将FieldSet上的字段 Map 到所提供对象上的 setter 一样,BeanWrapperFieldExtractor也需要名称 Map 到 getter 来创建对象数组。值得注意的是,名称的 Sequences 决定了数组中字段的 Sequences。

3.FlatFileItemReader 和 FlatFileItemWriter 使用案例

下一篇: FlatFileItemReader 和 FlatFileItemWriter 使用案例

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/800430.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

低空经济持续发热,无人机培训考证就业市场及前景剖析

随着科技的不断进步和社会需求的日益增长&#xff0c;低空经济已成为全球及我国经济增长的新引擎。作为低空经济的重要组成部分&#xff0c;无人机技术因其广泛的应用领域和显著的经济效益&#xff0c;受到了社会各界的广泛关注。为满足市场对无人机人才的需求&#xff0c;无人…

【动态规划1】斐波那契数列模型篇

文章目录 声明动态规划介绍1137.第N个泰波那契数题目描述分析代码 面试题 08.01. 三步问题题目描述分析代码 746.使用最小花费爬楼梯题目描述分析代码 91.解码⽅法题目描述分析代码 声明 本篇博客为动态规的基础篇&#xff0c;从零开始学习动态规划&#xff0c;如有错误&#…

MATLAB quiver矢量图 设置colorbar

给三维矢量图按照不同高度设置箭头颜色 figure clf X surfaceuz(:,1); Y surfaceuz(:,2); Z surfaceuz(:,3); hold onzcolor jet; % qquiver3(X,Y,Z,X,Y,W) for i 1:length(surfaceuz)quiver3(X(i),Y(i),Z(i),X(i),Y(i), Z(i),...Color,zcolor(floor((Z(i) - -0.1) * 2…

408数据结构-图的应用3-有向无环图、拓扑排序 自学知识点整理

前置知识&#xff1a;表达式&#xff0c;图的遍历 有向无环图描述表达式 有向无环图&#xff1a;若一个有向图中不存在环&#xff0c;则称为有向无环图&#xff0c;简称 D A G DAG DAG图 。 &#xff08;图片来自王道考研408数据结构2025&#xff09; 由王道考研-咸鱼学长的讲…

深圳晶彩智能JC3636W518C开箱实现电脑副屏功能

深圳晶彩智能发布了JC3636W518C 这是一款中国制造的&#xff0c;铝合金外壳&#xff0c;价格非常震撼的开发板。原创是billbill的up播主萨纳兰的黄昏设计的ESP32太极小派&#xff0c;由深圳晶彩智能批量生产。 该款 LCD 模块采用 ESP32-S3R8 芯片作为主控,该主控是双核 MCU&…

Vulnhub:DC-1

1.环境搭建 靶机下载地址 将下载的靶机导入到Oracle VM VirtualBox中&#xff0c;设置仅主机模式&#xff0c;使用和kali相同的网卡 2.渗透过程 使用nmap工具进行主机发现扫描 nmap -sn 192.168.56.0/24 发现靶机ip地址&#xff0c;使用nmap工具进行靶机端口扫描 nmap -sS…

一文说透Springboot单元测试

你好&#xff0c;我是柳岸花开。 一、单元测试说明 1 单元测试的优点与基本原则 一个好的单元测试应该具备以下FIRST 原则和AIR原则中的任何一条&#xff1a; 单元测试的FIRST 规则 Fast 快速原则&#xff0c;测试的速度要比较快&#xff0c; Independent 独立原则&#xff0c;…

Qt 多窗体、复用窗口的使用

1.继承自QWidge的窗口的呈现&#xff0c;作为tabPage呈现&#xff0c;作为独立窗口呈现 2.继承自QMainWindow的窗口的呈现&#xff0c;作为abPage呈现&#xff0c;作为独立窗口呈现 1. 继承自QWidge的窗口的呈现 1.1 作为tabPage呈现 void MutiWindowExample::on_actWidgetI…

AI绘画入门实践|Midjourney 提示词的使用技巧

提示词长短 尽可能做到简洁明了。 提示词很短 MJ 出图的随机性更高&#xff0c;创造的内容更有想象力&#xff0c;更适合创意发散的图像生成。 a dog 提示词很长 MJ 出图会更加精准&#xff0c;但描述太过详细&#xff0c;有可能出现AI理解不到位的情况。 越到后面的提示词&…

风险评估:IIS的安全配置,IIS安全基线检查加固

「作者简介」&#xff1a;冬奥会网络安全中国代表队&#xff0c;CSDN Top100&#xff0c;就职奇安信多年&#xff0c;以实战工作为基础著作 《网络安全自学教程》&#xff0c;适合基础薄弱的同学系统化的学习网络安全&#xff0c;用最短的时间掌握最核心的技术。 这一章节我们需…

Java面试八股之Redis集群Cluster

Redis集群Cluster Redis Cluster是一种基于数据分片&#xff08;Sharding&#xff09;的分布式缓存和存储系统&#xff0c;它实现了数据的水平扩展、高可用性和自动故障转移。以下是对Redis Cluster模式详细实现流程的描述&#xff1a; 1. 初始化与配置 部署节点&#xff1a…

flutter 手写 TabBar

前言&#xff1a; 这几天在使用 flutter TabBar 的时候 我们的设计给我提了一个需求&#xff1a; 如下 Tabbar 第一个元素 左对齐&#xff0c;试了下TabBar 的配置&#xff0c;无法实现这个需求&#xff0c;他的 配置是针对所有元素的。而且 这个 TabBar 下面的 滑块在移动的时…

产品经理-产品经理会在项目中遇到的几个问题(16)

项目中遇到了需求变更怎么办&#xff1f; 首先要弄清楚需求变更的原因是什么。如果是因为在迭代的过程中更好地理解了用户需求 进而产生了更好的需求则完全是正常的。如果是因为老板的需求 那就需要和老板沟通清楚&#xff0c;并且确保自己能理解老板的需求&#xff0c;而且这个…

软件测试——测试用例

工作职责&#xff1a; 1.负责产品系统测试&#xff0c;包括功能测试、性能测试、稳定性测试、用户场景测试、可靠性测试等。 2.负责测试相关文档的编写&#xff0c;包括测试计划、测试用例、测试报告等。 3.负责自动化测试框架、用例的维护。 岗位要求&#xff1a; 1.熟练…

800块,我从淘宝上买AGV……

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。 新书《智能物流系统构成与技术实践》人俱乐部 从淘宝上打算够购买一台AGV小车&#xff0c;上去一搜&#xff0c;嘿&#xff0c;你别说&#xff0c;还真有。便宜的才200块钱。 很兴奋把…

17-8 向量数据库之野望8 - 7 个主流向量数据库

​​​​​​ 在快速发展的人工智能 (AI)、机器学习 (ML) 和数据工程领域,对高效数据存储和检索系统的需求至关重要。矢量数据库已成为管理这些技术通常依赖的复杂高维数据的关键解决方案。在这里,我们探讨了每个 AI/ML/数据工程师都应该熟悉的七个矢量数据库,重点介绍了它们…

【Linux】01.Linux 的常见指令

1. ls 指令 语法&#xff1a;ls [选项] [目录名或文件名] 功能&#xff1a;对于目录&#xff0c;该命令列出该目录下的所有子目录与文件。对于文件&#xff0c;将列出文件名以及其他信息 常用选项&#xff1a; -a&#xff1a;列出当前目录下的所有文件&#xff0c;包含隐藏文件…

JavaSE学习笔记第三弹之异常抛出

今天我们继续来学习JavaSE相关的知识&#xff0c;希望与大家共同努力。 目录 异常 什么是异常 运行时异常 编译时异常 ​编辑 为什么需要异常处理机制 错误 异常的处理与抛出 异常处理 异常抛出 自定义异常 结语 异常 什么是异常 Java中异常是一种在程序运行时发…

Java二十三种设计模式-原型模式(5/23)

Java中的原型模式&#xff1a;深入解析与应用实践 引言 原型模式&#xff08;Prototype Pattern&#xff09;是一种创建型设计模式&#xff0c;它使用一个已有的对象作为原型&#xff0c;通过复制这个原型来创建新的实例。这种模式适用于对象的创建成本较高&#xff0c;或者对…

BL201分布式I/O耦合器连接Profinet网络

钡铼技术的BL201分布式I/O耦合器是一个用于Profinet网络的设备&#xff0c;用于连接远程输入/输出&#xff08;I/O&#xff09;设备到控制系统&#xff0c;如可编程逻辑控制器&#xff08;PLC&#xff09;&#xff0c;能够实现分布式的I/O连接和通信。 它支持标准Profinet IO …