CSV-анализ в Java – рабочий пример ..?

Я хочу написать программу для проекта Java Java для анализа некоторых CSV, которые я не знаю. Я знаю тип данных для каждого столбца, хотя я не знаю разделителя.

Проблема, которую я даже не знаю, как исправить, – это проанализировать Date или даже DateTime Columns. Они могут быть в одном из многих форматов.

Я нашел много библиотек, но не знаю, что лучше для моих нужд: http://opencsv.sourceforge.net/ http://www.csvreader.com/java_csv.php http://supercsv.sourceforge.net/ http : //flatpack.sourceforge.net/

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

Бьюсь об заклад, здесь много людей, у которых есть образец кода, который мог бы начать меня в кратчайшие сроки за то, что мне нужно:

  • автоматически разбивается на столбцы (неизвестный разделитель, известны типы столбцов)
  • отбрасывается в Columntype (должен справляться с $,% и т. д.)
  • конвертировать даты в объекты Java Date или Calendar

Было бы неплохо получить как можно больше примеров кода по электронной почте.

Большое спасибо! В ВИДЕ

Существует серьезная проблема с использованием

String[] strArr=line.split(","); 

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

Существует очень простой способ разобрать это:

 /** * returns a row of values as a list * returns null if you are past the end of the input stream */ public static List parseLine(Reader r) throws Exception { int ch = r.read(); while (ch == '\r') { //ignore linefeed chars wherever, particularly just before end of file ch = r.read(); } if (ch<0) { return null; } Vector store = new Vector(); StringBuffer curVal = new StringBuffer(); boolean inquotes = false; boolean started = false; while (ch>=0) { if (inquotes) { started=true; if (ch == '\"') { inquotes = false; } else { curVal.append((char)ch); } } else { if (ch == '\"') { inquotes = true; if (started) { // if this is the second quote in a value, add a quote // this is for the double quote in the middle of a value curVal.append('\"'); } } else if (ch == ',') { store.add(curVal.toString()); curVal = new StringBuffer(); started = false; } else if (ch == '\r') { //ignore LF characters } else if (ch == '\n') { //end of a line, break out break; } else { curVal.append((char)ch); } } ch = r.read(); } store.add(curVal.toString()); return store; } 

Для такого подхода есть много преимуществ. Обратите внимание, что каждый персонаж трогается ТОЧНО один раз. Впереди нет прочтения, отталкивания назад в буфере и т. Д. Не нужно искать до конца строки, а затем копировать строку перед parsingом. Этот анализатор работает исключительно из streamа и создает каждое строковое значение один раз. Он работает с строками заголовков и линиями данных, вы просто имеете дело с возвращаемым списком, соответствующим этому. Вы даете ему читателя, поэтому базовый stream был преобразован в символы с использованием любой выбранной вами кодировки. Поток может поступать из любого источника: файл, HTTP-сообщение, HTTP-получение и прямой анализ streamа. Это статический метод, поэтому нет объекта для создания и настройки, и когда это возвращается, память не сохраняется.

Вы можете найти полное обсуждение этого кода и почему этот подход предпочтительнее в моем сообщении в блоге на тему: «Только class, который вам нужен для файлов CSV» .

У вас также есть библиотека Apache Commons CSV , возможно, она делает то, что вам нужно. См. Руководство . Обновлено до версии 1.1 в 2014-11.

Кроме того, для надежной версии, я думаю, вам нужно будет ее самостоятельно закодировать … через SimpleDateFormat вы можете выбрать свои форматы и указать различные типы, если Date не похожа ни на один из ваших предварительно продуманных типов, это isn ‘Дата.

Мой подход не состоял бы в том, чтобы написать собственный API. Жизнь слишком коротка, и есть более насущные проблемы для решения. В этой ситуации я обычно:

  • Найдите библиотеку, которая, кажется, делает то, что я хочу. Если этого не существует, тогда реализуйте его.
  • Если библиотека существует, но я не уверен, что она будет подходящей для моих нужд, напишите ей тонкий API-интерфейс адаптера, чтобы я мог контролировать, как это называется. API-интерфейс адаптера выражает API, который мне нужен, и он отображает эти вызовы в базовый API.
  • Если библиотека не подходит, я могу поменять другую под API адаптера (будь то другой открытый источник или что-то, что я пишу сам) с минимальными усилиями, не затрагивая вызывающих абонентов.

Начните с того, что кто-то уже написал. Скорее всего, он сделает то, что вы хотите. Вы можете всегда писать свои собственные позже, если это необходимо. OpenCSV является такой же хорошей отправной точкой, как и любой другой.

Возможно, вы захотите ознакомиться с этой спецификацией для CSV. Имейте в виду, что официальной признанной спецификации нет.

Если вы сейчас не используете разделитель, это будет невозможно, так что вам нужно как-то это выяснить. Если вы можете выполнить ручную проверку файла, вы должны быстро увидеть, что это такое, и записать его в своей программе. Если разделитель может варьироваться, ваша единственная надежда состоит в том, чтобы иметь возможность вывести из форматирования известных данных. Когда Excel импортирует CSV-файлы, он позволяет пользователю выбирать разделитель, и это решение вы также можете использовать.

Мне пришлось использовать парсер csv около 5 лет назад. Кажется, существует по крайней мере два стандарта csv: http://en.wikipedia.org/wiki/Comm-separated_values и что делает Microsoft в excel.

Я нашел этот libaray, который ест оба: http://ostermiller.org/utils/CSV.html , но afaik, он не может вывести, какой тип данных были столбцами.

Я согласен с @Brian Clapper. Я использовал SuperCSV как парсер, хотя у меня были смешанные результаты. Мне нравится его универсальность, но в моих собственных файлах csv есть некоторые ситуации, для которых я еще не смог примирить «все же». Я верю в этот продукт и рекомендую его в целом – я просто пропустил что-то простое, без сомнения, что я делаю в своей собственной реализации.

SuperCSV может анализировать столбцы в различных форматах, редактировать изменения в столбцах и т. Д. Это стоит посмотреть. У этого есть также примеры, и легко следовать.

Единственное ограничение, которое у меня есть, – это поймать «пустой» столбец и разобрать его в Integer или, может быть, пробел и т. Д. Я получаю ошибки с нулевым указателем, но javadocs предлагает, чтобы каждый cellProcessor сначала проверял значения null. Итак, сейчас я обвиняю себя в этом. 🙂

В любом случае, взгляните на SuperCSV. http://supercsv.sourceforge.net/

Как минимум вам понадобится знать разделитель столбцов.

В основном вам нужно будет прочитать файл по строкам.

Затем вам нужно разделить каждую строку на разделитель, например запятую (CSV означает значения, разделенные запятыми), с

 String[] strArr=line.split(","); 

Это превратит его в массив строк, который вы затем можете манипулировать, например, с помощью

 String name=strArr[0]; int yearOfBirth = Integer.valueOf(strArr[1]); int monthOfBirth = Integer.valueOf(strArr[2]); int dayOfBirth = Integer.valueOf(strArr[3]); GregorianCalendar dob=new GregorianCalendar(yearOfBirth, monthOfBirth, dayOfBirth); Student student=new Student(name, dob); //lets pretend you are creating instances of Student 

Вам нужно будет сделать это для каждой строки, чтобы этот код превратился в цикл while. (Если вы не знаете, что разделитель просто открывает файл в текстовом редакторе.)

Я бы порекомендовал вам начать с того, что вы разделите свою задачу на части.

  1. Чтение строковых данных из CSV
  2. Преобразование строковых данных в соответствующий формат

Как только вы это сделаете, должно быть довольно тривиально использовать одну из библиотек, на которые вы ссылаетесь (что, безусловно, будет обрабатывать задачу № 1). Затем перебирайте возвращаемые значения и преобразуйте каждое значение String в нужное значение.

Если вопрос заключается в том, как преобразовать строки в разные объекты, это будет зависеть от того, с какого формата вы начинаете, и от какого формата вы хотите завершить работу.

DateFormat.parse (), например, будет анализировать даты из строк. См. SimpleDateFormat для быстрого построения DateFormat для определенного строкового представления. Integer.parseInt () будет целовать целые числа из строк.

Валюта, вам придется решить, как вы хотите ее захватить. Если вы хотите просто захватить как float, то Float.parseFloat () выполнит трюк (просто используйте String.replace (), чтобы удалить все $ и запятые перед его синтаксическим анализом). Или вы можете проанализировать BigDecimal (так что у вас нет проблем округления). Может быть лучший class для обработки валюты (я не делаю этого, поэтому не знаком с этой областью JDK).

Написание собственного анализатора – это весело, но, скорее всего, вы должны взглянуть на Open CSV . Он предоставляет множество способов доступа к CSV, а также позволяет создавать CSV. И он правильно справляется с экранами. Как уже упоминалось в другом сообщении, в Apache Commons есть также библиотека CSV-parsing, но она еще не выпущена.

  • Пользовательский десериализатор JSON с использованием Gson
  • SwingPropertyChangeSupport для динамического обновления JTextArea
  • o отобразить изображение
  • Классы classов Hibernate должны быть Serializable?
  • Как изменить TIMEZONE для java.util.Calendar / Date
  • Java: как разбить строку на несколько символов?
  • логический выражающий парсер в java
  • Как получить последнюю дату определенного месяца с помощью JodaTime?
  • Как исправить «Выражение типа List требует непроверенного преобразования ...»?
  • Retrofit 2.0 как получить десериализованную ошибку response.body
  • Почему у нас нет статического метода в (нестационарном) внутреннем classе?
  • Interesting Posts

    «Сообщение об ошибке Parser: не удалось загрузить тип» в Global.asax

    Java: как эффективно проверить нулевые указатели

    Объект или сложный тип ” не могут быть сконструированы в запросе LINQ to Entities

    Как сделать мигающий / мигающий текст с помощью CSS 3?

    Как сделать раскрывающийся список «Проверка данных» исключать пробелы?

    JSON Недопустимый средний байт UTF-8

    Как вы знаете переменный тип в java?

    Может ли панель разблокировки OS X запускать логин, похожий на loginwindow?

    Лучше ли создать одноэлементный доступ к контейнеру единства или передать его через приложение?

    Преобразовать число с плавающей запятой в определенную точность, а затем скопировать в строку

    Rails: перенаправить все неизвестные маршруты в root_url

    Странное поведение функции pow

    Иконки, исчезающие из области уведомлений (systray) под WinXP

    Уведомление о Heads-Up – Android Lollipop

    Что, по крайней мере, требуется для HTTP-запроса?

    Давайте будем гением компьютера.