Анализ CSV в java

У меня такая странная ситуация, когда я должен читать по горизонтали. Поэтому я получаю файл csv, который имеет данные в горизонтальном формате. Как ниже:

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

Все даты, показанные после RunDate, являются значениями для поля даты выполнения, и я должен обновить это поле для этой компании в своей системе. Значения даты не являются фиксированным числом, они могут быть одно значение от 10 до n. Поэтому мне нужно прочитать все эти значения и обновить в системе. Я пишу это на Java.

Ответ 1

Библиотеки, такие как OpenCSV обрабатывают все странные случаи для файлов CSV (новые строки, разграничение и т.д.).

Ответ 2

Строка, split ( "," ) вряд ли будет работать.
Он разделяет поля, содержащие встроенные запятые ( "Foo, Inc." ), хотя они представляют собой одно поле в строке CSV.

Что, если название компании:
          Company, Inc.

или хуже:
        Joe "Хорошая, быстрая и дешевая" еда


Согласно Wikipedia:     (http://en.wikipedia.org/wiki/Comma-separated_values)

Поля со встроенными запятыми должны быть заключены в символы двойной кавычки.

   1997,Ford,E350,"Super, luxurious truck"

Поля со встроенными символами двойной кавычки должны быть заключены в символы двойной кавычки, и каждый из вложенных символов двойной кавычки должен быть представлен парой символов двойной кавычки.

   1997,Ford,E350,"Super ""luxurious"" truck"


Хуже того, цитируемые поля могут иметь встроенные разрывы строк (новые строки, "\n" ):

Поля со встроенными разрывами строк должны быть заключены в символы двойной кавычки.

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



Это демонстрирует проблему с Разделительными парами разметки String, split ( "," ):

Строка CSV:

a, b, c, "Company, Inc.", d, e, "Joe" "Хорошие, быстрые и дешевые", "Food", f, 10/11/2010,1/1/2011, g, h, i


// Test String.split(",") against CSV with
// embedded commas and embedded double-quotes in
// quoted text strings:
//
// Company names are:
//        Company, Inc.
//        Joe "Good, Fast, and Cheap" Food
//
// Which should be formatted in a CSV file as:
//        "Company, Inc."
//        "Joe ""Good, Fast, and Cheap"" Food"
//
//
public class TestSplit {
    public static void TestSplit(String s, String splitchar) {
        String[] split_s    = s.split(splitchar);

        for (String seg : split_s) {
            System.out.println(seg);
        }
    }


    public static void main(String[] args) {
        String csvLine = "a,b,c,\"Company, Inc.\", d,"
                            + " e,\"Joe \"\"Good, Fast,"
                            + " and Cheap\"\" Food\", f,"
                            + " 10/11/2010,1/1/2011, h, i";

        System.out.println("CSV line is:\n" + csvLine + "\n\n");
        TestSplit(csvLine, ",");
    }
}


Производит следующее:


D:\projects\TestSplit>javac TestSplit.java

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


a
b
c
"Company
 Inc."
 d
 e
"Joe ""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 ""Good, Fast, and Cheap"" Food"
 f
 10/11/2010
1/1/2011
 g
 h
 i

Ответ 3

Как было предложено для разделения и синтаксического анализа, вы можете использовать opencsv

Для простых данных разделите их на "," и проанализируйте, а затем "Использовать список", чтобы добавить все эти значения.

Ответ 4

Файл CSV является \n завершенным файлом, в котором каждый столбец может быть разделен:

  • Запятая или
  • Вкладки \t

Я предлагаю вам иметь BufferedReader, который читает CSV файл и использует метод readLine() для чтения строки.

Из каждой строки используйте String.split(arg), где arg будет вашей запятой или вкладкой \t, чтобы иметь массив столбцов... оттуда вы знаете, что делать.

Ответ 5

используйте java.util.Scanner - вы можете вызвать useDelimiter(), чтобы сделать запятую вашим разделителем и прочитать новые токены с next(). Сканер можно создать непосредственно из вашего файла или строки, считанной из файла.

Ответ 6

На сегодняшний день наиболее полезной страницей по анализу CSV, который я когда-либо находил, является следующее:

http://secretgeek.net/csv_trouble.asp

В принципе, получите созданную библиотеку, чтобы сделать это за вас, потому что синтаксический анализ csv обманчив.

Ответ 7

Вы действительно должны попробовать univocity-parsers, поскольку его парсер CSV имеет множество функций для обработки всех видов угловых случаев (неэкранированные кавычки, смешанные разделители строк, BOM-кодированные файлы, и т.д.), который также является одним из самых быстрых CSV-библиотек.

Простой пример для анализа файла:

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.

Раскрытие информации: Я являюсь автором этой библиотеки. Это с открытым исходным кодом и бесплатно (лицензия Apache V2.0).

Ответ 8

Вы начинаете с чтения всей строки в строку. Затем вы используете функцию String.split(...) для получения всех токенов в строке, где используется разделитель, ",". (или это "\", когда вы используете регулярное выражение?)

Ответ 9

Чтобы получить каждое значение по одному за раз, используйте StringTokenizer. Постройте его с помощью StringTokenizer(str, ","). (не рекомендуется)

Используйте метод split() класса string, который загружает все токены в массив.

Используйте класс DateFormat для синтаксического анализа каждой даты - в частности DateFormat.parse(String).