在读取csv文件时无法移动到下一行

时间:2015-09-07 11:53:43

标签: java scala csv

我有一个类帮助我读取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
  }
}

这是PurchaseInfo类,它正在创建csv的每一行的对象:

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的方法获取一系列purchaseInfos,并在此seq中调用每个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调用addInvoiceFlow只有一个与第一个purchaseInfo并停止...为什么?我检查了34行,所以csv文件没有问题..

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

2 个答案:

答案 0 :(得分:4)

我怀疑你在完成阅读之前以某种方式关闭了输入文件。我无法确定,因为您没有提供调用insertData的代码。要测试此假设,请尝试通过更改

read方法实现文件内容
reader.iteratorWithHeaders.toSeq

reader.iteratorWithHeaders.toList

如果之后有效,则表示您在使用数据之前关闭CSVReader

更新:在我原来的回答中,我对修复是正确的,但在我的解释中并不正确。正如@ som-snytt在他的回答中正确指出的那样,Stream.map没有意识到流,它只是定义了一个在实际实现流时应该进行的额外元素转换。因此,在某些情况下,在读取点处不实现流(因此创建携带的中间Map)可能是有用的,而是在map之后执行它,当实现将直接给你{{1}时} s,即

PurchaseInfo

答案 1 :(得分:0)

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

也可能只有\n

字符\r是回车符,而\n是新行的字符。 Windows使用成对\r\n来实现dos的向后兼容性。

Unix仅使用\n