Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.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
用java解析CSV_Java_Date_Csv - Fatal编程技术网

用java解析CSV

用java解析CSV,java,date,csv,Java,Date,Csv,我有一种奇怪的情况,我必须横向阅读。所以我得到了一个csv文件,它有水平格式的数据。如下图所示: CompanyName,RunDate,10/27/2010,11/12/2010,11/27/2010,12/13/2010,12/27/2010.... RunDate之后显示的所有日期都是RunDate字段的值,我必须在系统中更新该公司的该字段。日期值不是固定数字,它们可以是单个值到10到n的数字。所以我需要读取所有这些值并在系统中更新。我是用Java写这篇文章的。正如其他人所建议的,您可以

我有一种奇怪的情况,我必须横向阅读。所以我得到了一个csv文件,它有水平格式的数据。如下图所示:

CompanyName,RunDate,10/27/2010,11/12/2010,11/27/2010,12/13/2010,12/27/2010....

RunDate之后显示的所有日期都是RunDate字段的值,我必须在系统中更新该公司的该字段。日期值不是固定数字,它们可以是单个值到10到n的数字。所以我需要读取所有这些值并在系统中更新。我是用Java写这篇文章的。

正如其他人所建议的,您可以使用它进行拆分和解析


对于简单数据,按“,”拆分它们,并对其进行解析,然后使用List添加所有这些值

首先将整行读入字符串。然后使用String.split(…)函数获取行中使用分隔符为“,”的所有标记。(或者使用正则表达式时是“\,”吗?

为了一次获取一个值,请使用。使用
StringTokenizer(str,“,”)
构造它。(不推荐)

使用string类的
split()


使用该类来解析每个日期——特别是
DateFormat.parse(String)

使用java.util.Scanner——您可以调用useDelimiter()将逗号作为分隔符,并使用next()读取新标记。可以直接从您的文件或从文件中读取的字符串创建扫描仪。

CSV文件是一个以
\n
终止的文件,每个列可以通过以下方式分开:

  • 逗号或
  • 选项卡
    \t
我建议您使用
BufferedReader
读取CSV文件,并使用
readLine()
方法读取行


从每一行中,使用
String.split(arg)
其中
arg
将是逗号或制表符
\t
来拥有一个列数组……从那里,您知道该做什么。

到目前为止,我发现的关于CSV解析主题的最有用的页面如下:


D:\projects\TestSplit>javac TestSplit.java

D:\projects\TestSplit>java  TestSplit
CSV line is:
a,b,c,"Company, Inc.", d, e,"Joe's ""Good, Fast, and Cheap"" Food", f, 10/11/2010,1/1/2011, g, h, i


a
b
c
"Company
 Inc."
 d
 e
"Joe's ""Good
 Fast
 and Cheap"" Food"
 f
 10/11/2010
1/1/2011
 g
 h
 i

D:\projects\TestSplit>

基本上,找一个已建立的库来为您完成这项工作,因为csv解析非常棘手。

字符串、拆分(“,”)不太可能工作。
它将拆分嵌入逗号(“Foo,Inc.”)的字段,即使它们是CSV行中的单个字段。

如果公司名称为:
公司,股份有限公司
或者更糟:
乔的“好、快、便宜”食物


根据维基百科:()

嵌入逗号的字段必须包含在双引号字符内

   1997,Ford,E350,"Super, luxurious truck"
   1997,Ford,E350,"Super ""luxurious"" truck"
   1997,Ford,E350,"Go get one now  
   they are going fast"
具有嵌入双引号字符的字段必须包含在双引号字符中,并且每个嵌入双引号字符必须由一对双引号字符表示

   1997,Ford,E350,"Super, luxurious truck"
   1997,Ford,E350,"Super ""luxurious"" truck"
   1997,Ford,E350,"Go get one now  
   they are going fast"

更糟糕的是,带引号的字段可能有内嵌的换行符(换行符;“\n”):

嵌入换行符的字段必须用双引号字符括起来

   1997,Ford,E350,"Super, luxurious truck"
   1997,Ford,E350,"Super ""luxurious"" truck"
   1997,Ford,E350,"Go get one now  
   they are going fast"


这说明了字符串拆分(“,”)解析逗号的问题:

CSV行是:

a、 b,c,“公司”,d,e,“乔的”“好的,快的,便宜的”“食品”,f,2010年11月10日,2011年1月1日,g,h,i



产生以下结果:


D:\projects\TestSplit>javac TestSplit.java

D:\projects\TestSplit>java  TestSplit
CSV line is:
a,b,c,"Company, Inc.", d, e,"Joe's ""Good, Fast, and Cheap"" Food", f, 10/11/2010,1/1/2011, g, h, i


a
b
c
"Company
 Inc."
 d
 e
"Joe's ""Good
 Fast
 and Cheap"" Food"
 f
 10/11/2010
1/1/2011
 g
 h
 i

D:\projects\TestSplit>


其中,CSV行应解析为:


a
b
c
"Company, Inc."
 d
 e
"Joe's ""Good, Fast, and Cheap"" Food"
 f
 10/11/2010
1/1/2011
 g
 h
 i
你真的应该试试 因为它的CSV解析器提供了许多特性来处理各种各样的角点情况(未转义引号、混合行分隔符、BOM编码文件等),这也是一种常见的方法

解析文件的简单示例:

CsvParserSettings settings = new CsvParserSettings(); //heaps of options here, check the docs
CsvParser parser = new CsvParser(settings);

//loads everything into memory, simple but can be slow.
List<String[]> allRows = parser.parseAll(new File("/path/to/your.csv"));

//parse iterating over each row
for(String[] row : parser.iterate(new File("/path/to/your.csv"))){
    //process row here
}

//and many other possibilities: Java bean processing, column selection, format detection, etc.
CsvParserSettings设置=新的CsvParserSettings()//这里有很多选项,请查看文档
CsvParser parser=新的CsvParser(设置);
//将所有内容加载到内存中,虽然很简单,但速度可能很慢。
List allRows=parser.parseAll(新文件(“/path/to/your.csv”);
//对每行进行迭代分析
for(String[]行:parser.iterate(新文件(“/path/to/your.csv”)){
//在这里处理行
}
//还有许多其他可能性:JavaBean处理、列选择、格式检测等。
披露:我是这个图书馆的作者。它是开源和免费的(Apache V2.0许可证)。

java.time 假设您正在使用CSV库读取文件,并假设您从该库中以字符串形式获取各个值:

    String valueFromCsvLibrary = "10/27/2010";
    try {
        LocalDate date = LocalDate.parse(valueFromCsvLibrary, dateFormatter);
        System.out.println("Parsed date: " + date);
    } catch (DateTimeParseException dtpe) {
        System.err.println("Not a valid date: " + dtpe);
    }
您应该更愿意将日期作为代码中的
LocalDate
处理(既不能作为字符串,也不能作为过时且设计拙劣的
Date
类的实例)

尽管我没有这方面的经验,但我确信我会选择一些开源的CSV库

仅当您确定CSV文件的值中不包含引号、虚线、逗号或其他复杂内容,并且出于某种原因选择手动解析时:

    String lineFromCsvFile = "CompanyName,RunDate,10/27/2010,11/12/2010,11/27/2010,12/13/2010,12/27/2010";
    String[] values = lineFromCsvFile.split(",");
    if (values[1].equals("RunDate")) {
        for (int i = 2; i < values.length; i++) {
            LocalDate date = LocalDate.parse(values[i], dateFormatter);
            System.out.println("Parsed date: " + date);
        }
    }

异常处理与以前一样进行,无需重复。

您只需调用
String.split(“,”)
。谢谢,我会尽量记住,我很少使用正则表达式。人们可能会将此视为“如何解析csv”的答案,这在列本身包含逗号时不起作用这并不像你想象的那样奇怪:)像这样的库处理CSV文件的所有奇怪情况(新行、定界等)。即使没有出现“奇怪”情况,使用库将(1)减少解析错误的机会;(2) 提供更多功能;(3) 产生一个可扩展的解决方案;和(4)随时集成未来CSV文件的解析(如果需要)。从
StringTokenizer
api中可以看出:StringTokenizer是一个遗留类,出于兼容性原因保留,尽管新代码中不鼓励使用它。建议任何寻求此功能的人使用String的split方法或java.util.regex包。注意:不好意思,在推荐答案之前,我可能应该先查阅文档@Qwerky-我讨厌他们扔掉了一个非常好的类-但是你是对的。我的猜测是它不是线程安全的,但我根本没有研究它。这不会起作用,因为CSV格式更复杂,只是值之间用