【问题标题】:Cant move to next line while reading csv file读取 csv 文件时无法移动到下一行
【发布时间】:2015-12-02 23:24:06
【问题描述】:

我有一个类可以帮助我读取 csv 文件,还有一个类可以为 csv 的每一行创建一个对象,因此我可以分别为每一行运行一些操作。将其用于自动化。

由于某种原因,我的程序在一行之后停止了......它之前工作过,所以我不知道出了什么问题..

这是我的 csv 阅读器类:

import java.io.File
import com.github.tototoshi.csv.CSVReader
import jxl.{Cell, Workbook}

import scala.collection.mutable

trait DataSource {

  def read (fileName: String): Seq[Map[String, String]]
}

object CsvDataSource extends DataSource {
  import com.github.tototoshi.csv.CSVFormat
  import com.github.tototoshi.csv.Quoting
  import com.github.tototoshi.csv.QUOTE_MINIMAL

  implicit object MyFormat extends CSVFormat {
    val delimiter: Char = '\t'
    val quoteChar: Char = '"'
    val escapeChar: Char = '"'
    val lineTerminator: String = "\r\n"
    val quoting: Quoting = QUOTE_MINIMAL
    val treatEmptyLineAsNil: Boolean = false
  }

  override def read(file: String): Seq[Map[String, String]] = {
    val reader = CSVReader.open(file, "UTF-16")(MyFormat)
    reader.iteratorWithHeaders.toSeq
  }
}

这是为 csv 的每一行创建一个对象的 PurchaseInfo 类:

case class PurchaseInfo(
                         something1: String,
                         something2: String,
                         something3: String,
                         something4: String) {
}


object PurchaseInfo {

    private def changeDateFormat(dateInString: String): String = {
    //System.out.println(dateInString)
    val formatter: SimpleDateFormat = new SimpleDateFormat("MMM dd, yyyy")
    val formatter2: SimpleDateFormat = new SimpleDateFormat("dd/MM/yyyy")
    val date: Date = formatter.parse(dateInString)
    return formatter2.format(date).toString
  }

    def fromDataSource (ds: DataSource)(fileName: String): Seq[PurchaseInfo] = {

      ds.read(fileName).map { c =>
        PurchaseInfo(
          something1 = c("Supplier Address Street Number"),
          something2 = c("Supplier Address Route"),
          something3 = c("Supplier Address Locality"),
          something4 = c("Supplier Address Postal Code")
        )
      }
    }
}

现在,在我执行所有操作的类中,有一个名为 insertData 的方法,它获取一个 purchaseInfo 序列,并在该序列中的每个 purchaseInfo 调用另一个方法....

def insertData (purchaseInfos: Seq[PurchaseInfo]) = {

    //logging in and then getting directed to the right path (where we start the invoices automation)
    login()

    val res = purchaseInfos.map { case purchaseInfo =>
      println(purchaseInfo.invoiceNumber)
      (purchaseInfo, Try(addInvoiceFlow(purchaseInfo)))
    }
    res
  }

问题是 insertData 仅使用第一个 purchaseInfo 调用 addInvoiceFlow 并停止...为什么?我检查了,有 34 行,所以 csv 文件没有问题..

这是用 scala 编写的,但 java 也可以提供帮助 :)

【问题讨论】:

  • 您没有展示insertDatapurchaseInfos 参数是如何构造的。您确定该序列中有多个条目吗?

标签: java scala csv


【解决方案1】:

您有一系列Stream.map。第一个iterator.toSeq 就是toStream

iteratorWithHeaders.toSeq map PurchaseInfo.apply map addInvoiceFlow

insertData 不会急切地评估 addInvoiceFlow 的调用,而只会评估 head 元素。

scala> (1 to 10).toStream map { i => println(s"Hi, $i") ; i + 1}
Hi, 1
res0: scala.collection.immutable.Stream[Int] = Stream(2, ?)

所以insertData 正在返回这个部分评估的流。

您可以强制评估:

scala> res0.force
Hi, 2
Hi, 3
Hi, 4
Hi, 5
Hi, 6
Hi, 7
Hi, 8
Hi, 9
Hi, 10
res1: scala.collection.immutable.Stream[Int] = Stream(2, 3, 4, 5, 6, 7, 8, 9, 10, 11)

还有this issue,以防您遇到解析错误。见this comment

【讨论】:

    【解决方案2】:

    我怀疑你在读完之前以某种方式关闭了输入文件。我无法确定,因为您没有提供调用insertData 的代码。为了验证这个假设,请尝试通过更改来实现 read 方法中文件的内容

    reader.iteratorWithHeaders.toSeq
    

    reader.iteratorWithHeaders.toList
    

    如果之后它会起作用,则意味着您在使用数据之前关闭了CSVReader


    更新:在我的原始答案中,我对修复的看法是正确的,但在我的解释中并不正确。正如@som-snytt 在他的回答中正确指出的那样,Stream.map 没有实现流,它只是定义了在实际实现流时应该进行的附加元素转换。因此,在某些情况下,在读取点不实现流(从而创建随身携带的中间Maps)可能很有用,而是在map之后执行,实现时会直接给您PurchaseInfos,即

    ds.read(fileName).map { c => PurchaseInfo(...)}.force
    

    【讨论】:

      【解决方案3】:

      检查行终止符是否为序列\r\n

      也可能只有\n

      \r 是回车符,\n 是换行符。 Windows 使用 \r\n 来实现与 dos 的向后兼容性。

      Unix 仅使用 \n

      【讨论】:

      • 一般来说Java IO类读取文本文件并不关心行尾。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-11
      • 2019-05-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多