关于USB转并口打印机net use端口映射建立、删除的问题

本文介绍了在Win7系统环境下,如何使用net use命令进行USB转并口打印机的端口映射,以及如何删除映射。详细步骤包括创建和删除LPT1端口的映射,以便通过共享打印机进行打印。同时,提出了在程序中使用CreateFile()函数打开LPT1端口遇到的问题,寻求解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

工作环境(蓝色粗体字为特别注意内容)

1,系统环境:Win7 Ultimate sp1

在以前老的主机上默认带25针的db25打印机接口的,但是随着主机的更新换代,这个“大而无用”的并口逐渐淡出了人们的视野。但如今仍然有很多并口设备在默默工作着,比如小票打印机,老式打印机等,我们知道在带串口的主机上,可以在cmd命令行中敲入以下代码:

copy test.txt LPT1

这样就能够将当前目录中test.txt文档中的内容经过LPT1(并口)打印出去。当然,如果电脑中不存在此端口,则会报错。为了能够实现以上命令,可以将某打印机映射到以上端口即(LPT1),在cmd命令行中敲入以下命令:

net use LPT1 \\127.0.0.1\VirtualPrinter /PERSISTENT:YES

如果该名称为“VirtualPrinter”的共享打印机不在本机上,则将IP地址“127.0.0.1”改为该共享打印机所在的主机IP,即能够通过该IP找到“VirtualPrinter”这台打印机。命令执行完毕,再次敲入:

net use

回车,将会得到以下映射信息:

New connections will be remembered.


Status       Local     Remote                    Network

-------------------------------------------------------------------------------
OK           LPT1      \\127.0.0.1\VirtualPrinter
                                                Microsoft Windows Network
The command completed successfully.

如果想要删除映射则使用如下命令

net use LPT1 /d

这时候我们再次执行

copy test.txt LPT1

就能够成功打印出来了,但是如何在程序中使用CreateFile()函数打开LPT1呢?笔者尝试了多种方式均未能成功打开,希望各位朋友能够指点一二,不胜感激!

 

 

 

Flink 编程模型第2关:Flink 程序结构 任务描述 本关任务:使用 Flink 计算引擎完成 WordCount 代码。 相关知识 为了完成本关任务,你需要掌握: 1.Flink 程序结构框架介绍 Flink 程序结构框架介绍 和其他分布式处理引擎一样,Flink 应用程序也遵循着一定的编程模式。不管是使用 DataStream API 还是 DataSet API 基本具有相同的程序结构。下面我们从一个 WordCount 程序说起,通过流式计算的方式实现对文本文件中的单词数量进行统计,然后将结果输出在给定路径中。 Streaming WordCount 实例代码 import org.apache.flink.api.java.utils.ParameterTool import org.apache.flink.streaming.api.scala._ import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment object WordCount { def main(args: Array[String]): Unit = { //第一步:设定执行环境设定 val env=StreamExecutionEnvironment.getExecutionEnvironment //第二步:指定数据源地址,读取输入数据 val text: DataStream[String] = env.readTextFile("wordcount.txt") //第三步:对数据集指定换操作逻辑 val counts: DataStream[(String, Int)] = text.flatMap(_.toLowerCase.split(" ")) .filter(_.nonEmpty) .map((_, 1)) .keyBy(0) .sum(1) //第四步:指定计算结果输出位置 //获取参数 val params = ParameterTool.fromArgs(args) //如果没有指定输出,则默认打印到控制台 if (params.has("output")) { //指定输出 //执行环境默认的并行度是:4,这边设置SocketSink的并行度:1 counts.writeAsText(params.get("output")).setParallelism(1); } else { System.out.println("Printing result to stdout. Use --output to specify output path."); //控制台打印 counts.print(); } //第五步:指定名称并触发流式任务 env.execute("Streaming WordCount") } } 整个 Flink 程序一共分为 5 步,分别为设定 Flink 执行环境、创建和加载数据集、对数据集指定换操作逻辑、指定计算结果输出位置、调用 execute 方法触发程序执行。对于所有的 Flink 应用程序基本都含有这 5 个步骤,下面将详细介绍每个步骤。 1.Execution Environment 运行 Flink 程序第一步就是获取相应的执行环境,执行环境决定了程序执行在什么环境(例如本地运行环境或者集群运行环境)中。同时不同的运行环境决定了应用的类型,批量处理作业和流式处理作业分别使用的是不同的 Execution Environment。例如 StreamExecutionEnvironment 是用来做流式数据处理环境,ExecutionEnvironment 是批量数据处理环境。可以使用三种方式获取 Execution Environment,例如 StreamExecution-Environment。 //设定 Flink 运行环境,如果在本地启动则创建本地环境,如果是在集群上启动,则创建集群环境。 StreamExecutionEnvironment.getExecutionEnvironment //指定并行度创建本地执行环境 StreamExecutionEnvironment.createLocalEnvironment(5) //指定远程 JobManagerIP 和 RPC 端口以及运行程序所在 jar 包及其依赖包 StreamExecutionEnvironment.createRemoteEnvironment("JobManagerHost",6021,5,"/user/application.jar") 其中第三种方法可以直接从本地代码中创建与远程集群的 Flink JobManager 的 RPC 连接,通过指定应用程序所在的 jar 包,将运行程序远程拷贝到 JobManager 节点上,然后将 Flink 应用程序运行在 远程的环境中,本地程序相当于一个客户端。 和 StreamExecutionEnvironment 构建过程一样,开发批量应用需要获取 Execution-Environment 来构建批量应用开发环境,如以下代码实例通过调用 ExecutionEnvironment 的静态方法来获取批计算环境。 //设定FlinK运行环境,如果在本地启动则创建本地环境,如果是在集群上启动,则创建集群环境 ExecutionEnvironment.getExecutionEnvironment //指定并行度创建本地执行环境 ExecutionEnvironment.createLocalEnvironment(5) //指定远程 JobManagerIP 和 RPC 端口以及运行程序所在 jar 包及其依赖包 ExecutionEnvironment.createRemoteEnvironment("JobManagerHost",6021,5,"/user/application.jar") 针对 Scala 和 Java 不同的编程语言环境,Flink 分别制定了不同的语言同时分别定义了不同的 Execution Environment 接口。StreamExecutionEnvironment Scala 开发接口在 org.apache.flink.streaming.api.scala 中,Java 开发接口在 org.apache.flink.streaming.api.java包中;ExecutionEnvironment Scala 接口在 org.apache.flink.api.scala 包中,Java 开发接口在org.apache.flink.api.java 包中。用户使用不同语言开发 Flink 应用时需要引入不同环境对应的执行环境。 2.初始化数据 创建完成 ExecutionEnvironment 后,需要将数据引入到 Flink 系统中。Execution-Environment 提供不同的数据接入接口完成数据的初始化,将外部数据换成 DataStream<T>或 DataSet<T> 数据集。如以下代码所示,通过调用 readTextFile()方法读取 file:///pathfile路径中的数据并换成 DataStream<String>数据集。 val text: DataStream[String] = env.readTextFile("wordcount.txt") 通过读取文件并换为 DataStream[String]数据集,这样就完成了从本地文件到分布式数据集的换,同时在 Flink 中提供了多种从外部读取数据的连接器,包括批量和实时的数据连接器,能够将 Flink 系统和其他第三方系统连接,直接获取外部数据。 3.执行换操作 数据外部系统读取并换成 DataStream 或者 DataSet 数据集中,下一步就将对数据集进行各种换操作。Flink中的 Transformation 操作都是通过不同的 Operator 来实现,每个 Operator 内部通过实现 Function 接口完成数据处理逻辑的定义。在 DataStream API 和 DataSet API 提供了大量的换算子,例如 map、flatMap、filter、keyBy等,用户只需要定义每种算子执行的函数逻辑,然后应用在数据换操作 Dperator 接口中即可。如下代码实现了对输入的文本数据集通过 FlatMap 算子换成数组,然后过滤非空字段,将每个单词进行统计,得到最后的词频统计结果。 val counts: DataStream[(String, Int)] = text .flatMap(_.toLowerCase.split(" "))//执行 FlatMap 换操作,_ 代表该行数据内容,toLowerCase换小写,并通过空格切割 .filter(_.nonEmpty)//执行 Filter 操作过滤空字段 .map((_, 1))//执行 map 换操作,换成 key-value 接口 .keyBy(0)//按照制定 key 对数据重分区 .sum(1)//执行求和运算操作 在上述代码中,通过 Scala 接口处理数据,极大地简化数据处理逻辑的定义,只需要通过传入相应 Lambda 计算表达式,就能完成 Function 定义。特殊情况下用户也可以通过实现 Function 接口来完成定义数据处理逻辑。然后将定义好的 Function 应用在对应的算子中即可。Flink 中定义 Function 的计算逻辑可以通过如下几种方式完成定义。 (1)通过创建 Class 实现 Function 接口 Flink 中提供了大量的函数供用户使用,例如以下代码通过定义 MyMapFunction Class 实现 MapFunction 接口,然后调用 DataStream 的 map() 方法将 MyMapFunction实现类传入,完成对实现将数据集中字符串记录换成大写的数据处理。 val dataStream: DataStream[String] = env.fromElements("hello", "flink") dataStream.map(new MyMapFunction).print() class MyMapFunction extends MapFunction[String,String]{ override def map(t: String): String = {t.toUpperCase()} } 执行程序结果输出: 1> HELLO 2> FLINK (2)通过创建匿名类实现 Function 接口 除了以上单独定义 Class 来实现 Function 接口指出,也可以直接在 map() 方法中创建匿名实现类的方式定义函数计算逻辑,例如以下代码获取元素的平方。 val env = StreamExecutionEnvironment.getExecutionEnvironment val dataStream: DataStream[Integer] = env.fromElements(4, 2, 3, 12, 16,8,1,6,90,14,17,4,9) //通过实现 MapFuncion 匿名实现类来定义map函数计算逻辑 dataStream.map(new MapFunction[Integer,Integer] { override def map(t: Integer): Integer = { t*t } }) 执行程序结果输出: 2> 9 2> 1 2> 289 1> 4 1> 64 1> 196 3> 144 3> 36 3> 16 4> 16 4> 256 4> 8100 4> 81 (3)通过实现 RichFunction接口 前面提到的换操作都实现了 Function 接口,例如 MaoFunction 和 FlatMap-Function接口,在 Flink 中同时提供了 RichFunction 接口,主要用于比较高级的数据处理场景,RichFunction 接口中有 open、close、getRuntimeContext 和 setRuntimeContext 等方法来获取状态、缓存等系统内部数据。和 MapFunction 相似,RichFunction 子类中也有 RichMap-Function,如下代码通过实现 RichMapFunction 定义数据处理逻辑。 val env = StreamExecutionEnvironment.getExecutionEnvironment val dataStream: DataStream[String] = env.fromElements("123", "321","258","666") //定义匿名实现 RichMapFunction 接口,完成对字符串到整形数字的换 dataStream.map(new RichMapFunction[String,Int] { override def map(in: String): Int = {in.toInt} }).print() env.execute() 执行程序结果输出: 3> 258 1> 123 4> 666 2> 321 4.分区 key 指定 在 DataStream 数据经过不同的算子换过程中,某些算子需要根据指定的 key 进行换,常见的有 join、coGroup、groupBy类算子,需要先将 DataStream 或 DataSet 数据集换成对应的 KeyedStream 和 GroupedDataSet,主要目的是将相同 key 值的数据路由到相同的 Pipeline 中,然后进行下一步的计算操作。需要注意的是,在 Flink 中这种操作并不是真正意义上将数据集换为 Key-Value 结构,而是一种虚拟 key,目的仅仅是帮助后面的基于 Key 的算子使用,分区 key 可以通过两种方式指定: (1)根据字段位置指定 在 DataStream API 中通过 keyBy() 方法将 DataStream 数据集根据指定的 key 换成重新分区 KeyedStream,如以下代码所示,对数据集按照相同key进行sum()聚合操作。 val env = StreamExecutionEnvironment.getExecutionEnvironment val dataStream: DataStream[(String, Int)] = env.fromElements(("a", 1), ("c", 2),("a", 1),("a", 1),("a", 1),("c", 1)) //根据第一个字段重新分区,然后对第二个字段进行求和运算 dataStream.keyBy(0).sum(1).print() env.execute() 执行程序结果输出: 2> (c,2) 2> (c,3) 3> (a,1) 3> (a,2) 3> (a,3) 3> (a,4) 在 DataSet API 中,如果对数据根据某一条件聚合数据,对数据进行聚合时候,也需要对数据进行重新分区。如以下代码所示,使用 DataSet API 对数据集根据第一个字段作为 GroupBy 的 key,然后对第二个字段进行求和运算。 val env = ExecutionEnvironment.getExecutionEnvironment val dataSet = env.fromElements(("hello", 1), ("flink", 3),("hello", 5),("hello", 3),("flink", 2)) //根据第一个字段进行数据重分区 val groupedDataSet: GroupedDataSet[(String, Int)] = dataSet.groupBy(0) //求取相同key 值下第二个字段的最大值 groupedDataSet.max(1).print() 执行程序结果输出: (flink,3) (hello,5) (2)根据字段名称指定 KeyBy 和 GroupBy 的 Key 除了能够通过字段位置来指定之外,也可以根据字段的名称来指定。使用字段名称需要 DataStream 中的数据结构类型必须是 Tuple 类或者 POJO 类。如以下代码所示,通过指定 name 字段名称来确定 groupby 的 key 字段。 //使用 POJO 类,要将类写在 main 方法外面 case class Persion(name: String, age: Int) def main(args: Array[String]): Unit = { val env = ExecutionEnvironment.getExecutionEnvironment val dataSet = env.fromElements(Persion("Alex",18),Persion("Peter",43),Persion("Alex",35)) //指定 name 字段名称来确定 groupby 字段 dataSet.groupBy("name").max(1).print() } 执行程序结果输出: Persion(Alex,35) Persion(Peter,43) 如果程序使用 Tuple 数据类型,通常情况下字段名称从 1 开始计算,字段位置索引从 0 开始计算,以下代码中两种方式是等价的。 val env = ExecutionEnvironment.getExecutionEnvironment val dataSet = env.fromElements(("Alex",18),("Peter",43),("Alex",35)) //通过名称指定第一个字段名称 dataSet.groupBy("_1").max(1).print() //通过位置指定第一个字段 //dataSet.groupBy(0).max(1).print() 执行程序结果输出: (Alex,35) (Peter,43) 5.输出结果 数据集经过换操作之后,形成最终的结果数据集,一般需要将数据集输出在外部系统中或者输出在控制台之上。在 Flink DataStream 和 DataSet 接口中定义了基本的数据输出方法,例如基于文件输出 writeAsText(),基于控制台输出 print() 等。同时 Flink 在系统中定义了大量的 Connector,方便用户和外部系统交互,用户可以直接通过调用 addSink() 添加输出系统定义的 DataSink 类算子,这样就能将数据输出到外部系统。以下实例调用 DataStream API 中的 writeAsText()和print()方法将数据集输出在文件和客户端中。 //将数据输出到文件中 counts.writeAsText("savafile") //将数据输出控制台 counts.print() 6.程序触发 所有的计算逻辑全部操作定义好后,需要调用 ExecutionEnvironment 的 execute() 方法来触发应用程序的执行,其中 execute() 方法返回的结果类型为 JobExecutionResult,里面包含了程序执行的时间和累加器等指标。需要注意的是,execute() 方法运行程序,如果不调用则 Flink 流式程序不会执行,但对于 DataSet API 输出算子中以及包含对 execute() 方法的调用,则不需要显性调用 execute() 方法,否则会出现程序异常。 //调用 StreamExecutionEnvironment 的 execute 方法执行流式应用程序 env.execute("APP Name") 编程要求 根据提示,在右侧编辑器补充代码,完成 WordCount 程序。 使用 ExecutionEnvironment 获取批计算环境; 使用 readTextFile 方法读取 /root/files/wordcount.txt 数据; 将读取到的数据存放人 DataSet 内并开始执行换操作; 使用 flatMap 算子完成对数据换大小写并切割 使用 filter 算子筛选为空的数据 使用 map 算子将单词变为元组型式数据:(word,1) 使用 groupBy 算子对word进行分区 使用 sum 算子对各值进行相加 将数据输出至文件/root/files/result.txt文件中。 调用 execute() 方法使得程序触发。 测试说明 平台会对你编写的代码进行测试: 测试输入:无; 预期输出: (and,2) (as,4) (be,1) (beast,2) (beauty,2) (before,1) (can,1) (ever,2) (it,1) (just,1) (old,1) (same,1) (tale,1) (the,3) (time,1) (true,1) 开始你的任务吧,祝你成功!
06-05
<think>首先,用户的问题是关于如何使用Flink编写WordCount程序,特别是使用ExecutionEnvironment和相关API来实现批处理版本的WordCount。用户提到了读取文件、数据换、分组求和以及输出结果到文件。用户参考了四个引用:-引用[1]:Flink1.17代码示例,使用DataStreamAPI实现批处理WordCount(处理有界数据流)。-引用[2]:Flink1.17代码示例,使用DataStreamAPI实现流处理WordCount(处理无界数据流)。-引用[3]:关于FlinkJavaAPI实现WordCount的批处理和流处理,提到截图和Job执行情况。-引用[4]:Flink入门WordCount批处理实现,涉及日志配置。用户明确表示这些引用仅供参考,我需要参考用户上一次的问题和我的回答。但在这个对话中,这是第一次交互,所以没有“上一次的问题”。用户说的是:“请尽可能多的参考用户上一次的问题和你的回答。”但在系统提示中,这是第一条用户消息。所以,我应该基于当前信息回答。用户要求的具体点是:-使用ExecutionEnvironment和相关API实现WordCount程序。-包括读取文件、数据换、分组求和、输出结果到文件的具体代码示例。从引用中:-引用[1]和[4]提到批处理WordCount。-引用[1]提到使用DataStreamAPI处理有界数据流(即批处理)。-ExecutionEnvironment是用于批处理的,而StreamExecutionEnvironment是用于流处理的。用户指定了“ExecutionEnvironment”,所以我应该用批处理的API。在Flink中:-批处理API使用ExecutionEnvironment。-流处理API使用StreamExecutionEnvironment。用户说:“使用Flink的ExecutionEnvironment和相关API”,所以这是批处理。代码结构应包括:1.创建执行环境。2.读取文件(使用readTextFile)。3.数据换:比如将行分割成单词。4.分组求和:groupBy操作后,sum。5.输出结果到文件。系统级指令:-行内数学表达式用$...$:在这个上下文中可能不需要。-独立公式用$$...$$:不需要数学公式。-LaTeX语法正确:但在代码块中,不需要LaTeX,代码用代码块。-使用中文回答。-生成相关问题:在回答末尾添加相关问题。-引用标识:在引用的内容末尾加[^1]等,但用户提供了引用,我不直接引用它们;用户在提问中引用了它们,所以我应该基于那些代码示例。回答结构:-清晰地解释步骤。-提供代码示例。-确保代码正确:根据引用[1],创建ExecutionEnvironment;引用[4]提到批处理。从引用[1]:它使用StreamExecutionEnvironment,但用户指定ExecutionEnvironment,所以我会用ExecutionEnvironment。标准批处理WordCount代码:-使用ExecutionEnvironment。-readTextFile读取文件。-flatMap分割单词。-groupBy(0)按单词分组。-sum(1)计数。-writeAsText输出。代码示例:基于引用,我可以给出Java代码。结束时生成相关问题。使用中文。代码示例格式:用代码块,如示例中的Python代码。系统提示中的示例是关于快速排序的,用Python代码块。我会用Java代码块。引用标识:用户已经在提问中引用了[^1],[^2],[^3],[^4],所以在我回答中,如果引用这些,可以在末尾加标识。但最好自然地融入,如“根据Flink文档[^1]”。用户说:“上述引用仅供参考”,所以我不必严格依赖,但可以参考。我的回答应包括:1.简要介绍。2.代码示例。3.解释步骤。4.输出到文件。5.结束相关问题。具体代码:基于FlinkExecutionEnvironment。在代码中,引用[1]使用StreamExecutionEnvironment,对于批处理,也可以用DataStreamAPI处理有界流,但用户指定ExecutionEnvironment,我会用DataSetAPI,因为ExecutionEnvironment是DataSetAPI的一部分。在Flink中:-ExecutionEnvironment用于DataSetAPI(批处理)。-StreamExecutionEnvironment用于DataStreamAPI(流处理)。用户指定了“ExecutionEnvironment”,所以我用DataSetAPI。代码类似:```javaExecutionEnvironmentenv=ExecutionEnvironment.getExecutionEnvironment();DataSet<String>text=env.readTextFile("path/to/file");DataSet<Tuple2<String,Integer>>counts=text.flatMap(newTokenizer()).groupBy(0).sum(1);counts.writeAsText("output/path");```其中Tokenizer是UDF。完整代码。解释步骤。相关问题:例如关于性能优化、不同场景等。引用:如果基于引用,添加[^n]。在回答中,自然地添加引用标识,如末尾。生成3-4个相关问题。</think> ### Flink 批处理 WordCount 实现 Apache Flink 是一个强大的分布式数据处理框架。使用 `ExecutionEnvironment` API 实现 WordCount 程序是 Flink 的常见入门示例,尤其适用于有界数据(如文件)的批处理场景。下面我将基于 Flink 1.17 的 Java API(与您提供的引用一致)[^1][^4],提供一个完整的代码示例,并逐步解释实现步骤。代码包括读取文件、数据换、分组求和和输出结果到文件,确保逻辑清晰且可运行。 #### 实现步骤 1. **创建执行环境**:使用 `ExecutionEnvironment` 初始化批处理上下文。 2. **读取文件**:加载本地或 HDFS 文件作为输入数据源。 3. **数据换**: - 使用 `flatMap` 分割每行文本为单词。 - 为每个单词映射为 `(word, 1)` 的形式,便于后续计数。 4. **分组求和**: - 基于单词分组(`groupBy`)。 - 求和每个组中的值(`sum`)。 5. **输出结果到文件**:将最终结果保存到指定路径。 #### 完整代码示例 以下是 Flink 批处理 WordCount 的 Java 代码。此代码示例基于 Flink 1.17 的 `DataSet` API(`ExecutionEnvironment`),运行后可在本地或集群上处理文件。[^1][^4] ```java import org.apache.flink.api.java.ExecutionEnvironment; import org.apache.flink.api.java.operators.DataSource; import org.apache.flink.api.java.tuple.Tuple2; import org.apache.flink.api.java.DataSet; import org.apache.flink.util.Collector; public class WordCountBatch { public static void main(String[] args) throws Exception { // 步骤 1: 创建执行环境 (ExecutionEnvironment 用于批处理) ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment(); // 步骤 2: 读取文件 (有界数据源, 替换为您的文件路径) DataSource<String> text = env.readTextFile("input.txt"); // 输入文件路径, 支持本地/HDFS // 步骤 3: 数据换 - 分割单词并映射为 (word, 1) DataSet<Tuple2<String, Integer>> words = text.flatMap(new Tokenizer()); // 步骤 4: 分组求和 - 按单词分组并求和频率 DataSet<Tuple2<String, Integer>> counts = words .groupBy(0) // 按 Tuple2 的第一个元素 (单词) 分组 .sum(1); // 对每个组的第二个元素 (1) 求和 // 步骤 5: 输出结果到文件 (指定输出路径) counts.writeAsText("output").setParallelism(1); // 输出目录, 可并行度配置 // 执行程序 env.execute("Flink Batch WordCount"); } // 自定义 Tokenizer 类 (用于分割单词) public static class Tokenizer implements org.apache.flink.api.common.functions.FlatMapFunction<String, Tuple2<String, Integer>> { @Override public void flatMap(String value, Collector<Tuple2<String, Integer>> out) { // 分割每行文本为单词 (正则表达式 \W+ 分割非字母数字字符) String[] words = value.toLowerCase().split("\\W+"); for (String word : words) { if (!word.isEmpty()) { out.collect(new Tuple2<>(word, 1)); // 输出 (word, 1) 键值对 } } } } } ``` #### 代码解释和关键点 - **创建执行环境**:`ExecutionEnvironment.getExecutionEnvironment()` 根据配置自动识别本地或集群模式。[^1] 在批处理中,它优化资源使用。 - **读取文件**:`readTextFile("input.txt")` 加载文件输入(确保文件存在)。支持绝对路径如 `"hdfs:///user/data/input.txt"`。 - **数据换**: - `flatMap(new Tokenizer())`:自定义 `Tokenizer` 函数将每行分割为单词并映射为 `(word, 1)`。这里使用正则表达式 `\W+` 处理标点符号[^1]。 - UDF(用户定义函数)扩展 `FlatMapFunction`,是 Flink 的核心机制。 - **分组求和**: - `groupBy(0)`:基于 Tuple2 的第一个元素(单词)分组,相当于 SQL 的 `GROUP BY`。 - `sum(1)`:对每个组的第二个元素(频率)求和,结果输出格式为 `(单词, 总频率)`。 - **输出到文件**: - `writeAsText("output")`:将结果写入 "output" 目录(文件形式)。 - `setParallelism(1)`:设置并行度为 1,确保单文件输出;移除后可并行处理以提高性能。[^1] - **执行程序**:`env.execute("Job Name")` 启动 Flink 作业。 - **日志配置**:引用[^4]提到日志设置(如 `log4j.properties`),在运行前配置日志级别以减少噪音(示例配置见最后)。 #### 运行示例 1. **准备文件**: - 创建 `input.txt`,内容例如: ``` Hello Flink Hello World Flink is fast ``` 2. **编译运行**: - 确保 Flink 1.17 依赖(Maven `pom.xml`): ```xml <dependencies> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-java</artifactId> <version>1.17.0</version> </dependency> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-clients</artifactId> <version>1.17.0</version> </dependency> </dependencies> ``` - 运行代码后,在 "output" 目录查看结果文件,内容类似: ``` (hello,2) (flink,2) (world,1) (is,1) (fast,1) ``` #### 日志配置示例(基于引用[^4]) 创建 `resources/log4j.properties`: ```properties log4j.rootLogger=error, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n ``` 此配置减少控制台输出,便于调试。[^4] #### 注意事项 - **有界数据流**:此示例处理文件作为有界流(批处理),适用于固定数据集。[^1] - **错误处理**:确保输入路径正确,否则抛出异常。在真实场景中添加异常捕获。 - **扩展性**:输出路径可替换为 Kafka/HDFS,以适应分布式环境。如需流处理(无界数据)版本,引用[^2]提供了 DataStream API 示例。 通过以上步骤,您能快速上手 Flink 批处理 WordCount,理解核心 API 的使用。若需优化或调试,Flink Web UI(如引用[^3]的截图)可帮助监控作业状态。[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值