Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala Akka:如何在一个图形阶段提取一个值并在下一个图形阶段使用它_Scala_Akka_Akka Stream_Alpakka - Fatal编程技术网

Scala Akka:如何在一个图形阶段提取一个值并在下一个图形阶段使用它

Scala Akka:如何在一个图形阶段提取一个值并在下一个图形阶段使用它,scala,akka,akka-stream,alpakka,Scala,Akka,Akka Stream,Alpakka,我正在使用Alpakka和Akka处理CSV文件。因为我有一堆CSV文件必须添加到同一个流中,所以我想添加一个包含文件名或请求信息的字段。目前我有这样的想法: val source = FileIO.fromPath(Paths.get("10002070.csv")) .via(CsvParsing.lineScanner()) 它流式处理ByTestRing(字段)的列表(行)序列。目标是: val filename = "10002070.csv" val source = File

我正在使用Alpakka和Akka处理CSV文件。因为我有一堆CSV文件必须添加到同一个流中,所以我想添加一个包含文件名或请求信息的字段。目前我有这样的想法:

val source = FileIO.fromPath(Paths.get("10002070.csv"))
  .via(CsvParsing.lineScanner())
它流式处理ByTestRing(字段)的列表(行)序列。目标是:

val filename = "10002070.csv"
val source = FileIO.fromPath(Path.get(filename))
    .via(CsvParsing.lineScanner())
    .via(AddCSVFieldHere(filename))
创建类似于以下内容的结构:

10002070.csv,max,estimated,12,1,0
其中文件名是原始源中不存在的字段

我觉得在流中注入值看起来不太好,而且最终我想确定在读取目录的流阶段中传递给解析的文件名


通过流阶段传递值以供以后重用的正确/规范方法是什么?

您可以使用
map
转换流,将文件名添加到每个
列表[ByteString]

val fileName = "10002070.csv"
val source =
  FileIO.fromPath(Path.get(fileName))
    .via(CsvParsing.lineScanner())
    .map(List(ByteString(fileName)) ++ _)
例如:

Source.single(ByteString("""header1,header2,header3
                           |1,2,3
                           |4,5,6""".stripMargin))
  .via(CsvParsing.lineScanner())
  .map(List(ByteString("myfile.csv")) ++ _)
  .runForeach(row => println(row.map(_.utf8String)))

// The above code prints the following:
// List(myfile.csv, header1, header2, header3)
// List(myfile.csv, 1, 2, 3)
// List(myfile.csv, 4, 5, 6)
同样的方法也适用于更一般的情况,即您事先不知道文件名。如果要读取目录中的所有文件(假设所有这些文件都是csv文件),将文件连接到单个流中,并在每个流元素中保留文件名,则可以使用Alpakka实用程序以以下方式执行此操作:

val source =
  Directory.ls(Paths.get("/my/dir")) // Source[Path, NotUsed]
    .flatMapConcat { path =>
       FileIO.fromPath(path)
         .via(CsvParsing.lineScanner())
         .map(List(ByteString(path.getFileName.toString)) ++ _)
    }

我会使用扇出,一个流用于内容,另一个流用于名称文件,必要时使用zip…是的,这是我正在考虑的解决方案。我遇到的问题是,在展开和处理流之后,元素1的数量与行的数量不同。当文件流结束时(文件大小不同),如何确保来自目录读取的流前进一次。也许mergePreferred会这样做,但我有点担心竞争条件。您是否试图为整个目录创建一个流?也许最好为每个文件生成一个流。我认为这样会更好,否则你应该创建某种加入流程。。如果我理解得很好。。