【问题标题】:CsvParser Stream Closed Error When Parsing Multiple Files解析多个文件时 CsvParser Stream Closed 错误
【发布时间】:2014-04-14 10:52:58
【问题描述】:

我正在尝试解析通过在目录上递归获得的 CSV 文件列表。下面的代码只打印一行,然后存在 Stream Closed Error :

def stageDir = new File(STAGE_DIR), listOfFiles = [], filesData = []
// Get the list of files
stageDir.eachFileRecurse(FileType.FILES) { file ->
   listOfFiles << file
}

// Start parsing each CSV file in the list
listOfFiles.each { file ->
   def csvData = file.withReader {
      new CsvParser().parse( it , separator: CSV_SEPARATOR )
   }

   // Here i put the returned csvData (of type CsvIterator) in the filesData
   filesData.add(csvData)
}

// I checked filesData and it's not empty, so i iterate over it.

// HERE I GET : Stream Closed error
// I'm just trying to test by printing the first line of myIt 
// (but is there a more efficient way to iterate over CsvIterator ?)
for (myIt in filesData) {
   println myIt[0].ID + " " + myIt[0].NAME
}

有没有更好的方法来使用 CsvParser 处理多个文件并避免 Stream Closed 错误?

【问题讨论】:

    标签: csv groovy ioexception


    【解决方案1】:

    过去,当文件关闭并且您尝试从中读取异常时,预期结果是。

    但不要害怕! OpenCSV 项目有一个新的活跃开发人员 Maciek,他不仅将项目更新到 Java 7(因为不再支持 5 和 6),他还更改了 CSVReader 以不抛出 IOException 而是安静地处理它.

    我们已经在Sourceforge as version 3.0 上推出了这个版本。请随时对其进行测试并将 xlson 库更新到新版本。

    我不得不说,看到我们的工作最终用于其他项目,我感到非常荣幸。这有点像吉他制造商发现著名摇滚乐队使用您的吉他。

    【讨论】:

      【解决方案2】:

      您不会将解析后的数据添加到filesData,但实际上是new File('').withReader{} 返回的结果,这可能是流或其他任何东西。而是尝试:

      listOfFiles.each { file ->
         def csvData = file.withReader {
            filesData.add(new CsvParser().parse( it , separator: CSV_SEPARATOR ))
         }
      }
      

      更新

      我也怀疑你是否正确地迭代了filesData。在每个循环中,myIt 不是数据行,而是从parse 方法返回的Iterable 的一个实例。目前无法进行试验,但也许应该这样做。

      for (myIt in filesData) {
         myIt.each { rowIt ->
           println rowIt.ID + " " + rowIt.NAME
         }
      }
      

      更新 2

      groovy 控制台的工作示例

      @Grab( 'com.xlson.groovycsv:groovycsv:1.0' )
      import com.xlson.groovycsv.CsvParser
      
      def csv1 = '''ID,NAME,ADDRESS
      1,n1,a1
      2,n2,a2
      3,n3,a3'''
      
      def csv2 = '''ID,NAME,ADDRESS
      4,n4,a4
      5,n5,a5
      6,n6,a6
      '''
      def listOfFiles = [csv1, csv2]
      def filesData = []
      
      listOfFiles.each { filesData.add(new CsvParser().parse( it , separator: ',' )) }
      
      filesData.each { d ->
          d.each { r ->
              println "$r.ID $r.NAME"
          }
      }
      

      您需要做的是检查您提供的示例中所有文件操作是否顺利运行。

      更新 3:D

      这是带有重现错误的示例代码:

      @Grab( 'com.xlson.groovycsv:groovycsv:1.0' )
      import com.xlson.groovycsv.CsvParser
      
      def f1
      def f2 
      
      try {
          f1 = File.createTempFile("temp1",".csv")
          f2 = File.createTempFile("temp2",".csv")
          f1.text = '''ID,NAME,ADDRESS
      1,n1,a1
      2,n2,a2
      3,n3,a3
      '''
      
          f2.text = '''ID,NAME,ADDRESS
      4,n4,a4
      5,n5,a5
      6,n6,a6
      '''
          def listOfFiles = [f1, f2]
          def filesData = []
      
          listOfFiles.each { f ->
              f.withReader { r -> 
                  def data = new CsvParser().parse( r , separator: ',' )
                  filesData.add(data)
              }
          }
      
          filesData.each { d ->
              d.each { r ->
                  println "$r.ID $r.NAME"
              }
          }
      } finally {
          f1?.delete()
          f2?.delete()
      }
      

      现在..这里发生了什么。在 withReader 闭包中,CsvParserparse 方法被调用,并传递了 r(读取器)对象。但是withReader 闭包不会被急切地评估,而是懒惰地。然后在打印解析数据的地方读取r,当groovy检测到EOF时自动关闭流(可以通过将3,n3,a3\n'''更改为3,n3,a3'''轻松验证。但是au.com.bytecode.opencsv.CSVReader类( getNextLine() 方法)不检查流是否已关闭并尝试读取它,这会导致 Stream closed 异常。实际上这是 CSVReader 类中的错误。

      要纠正它,您需要将懒惰的阅读更改为渴望。这可以通过更改这行代码来完成:

      filesData.add(data)
      

      到这里:

      filesData.add(data.toList())
      

      这会导致数据在闭包中被读取,而不是留给以后读取。

      【讨论】:

      • 仍然收到 java.io.IOException:Stream 在同一行关闭:println myIt[0].ID + " " + myIt[0].NAME !
      • 好的。网络上有任何示例项目吗?准备好了吗?
      • 我见过的样本处理一个文件,一个返回 CsvIterator 而不是多个文件:(
      • 好的,但是您在网上有什么示例项目可供我试用吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-17
      • 2012-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-15
      • 1970-01-01
      相关资源
      最近更新 更多