Автоопределение CSV в Java

Каким будет надежный способ автоматического определения того, что файл на самом деле является CSV, если CSV будет переопределен на "Character-Separated Values", т.е. данные, использующие любой отдельный символ (но обычно любой не алфавитно-цифровой символ) в качестве разделителя, а не только запятые?

По сути, при таком (пере)определении, CSV = DSV ("Delimiter-Separated Values"), обсуждаемый, например, в этой статье Википедии, тогда как формат "Comma-Separated Values" определен в RFC 4180.

Более конкретно, существует ли метод статистического вывода о том, что данные имеют какую-то "фиксированную" длину, то есть "возможный CSV"? Просто подсчет количества разделителей не всегда работает, потому что существуют CSV-файлы с переменным количеством полей на запись (т.е. записи, которые, вопреки требованиям RFC 4180, не имеют одинакового количества полей в одном файле).

Распознавание CSV представляется особенно сложной проблемой, особенно если распознавание не может основываться на расширении файла (например, при чтении потока, который не имеет такой информации).

Правильное ("полное") автоопределение требует как минимум 4 решения для надежного принятия:

  1. Определение того, что файл действительно является CSV
  2. Определение наличия заголовков
  3. Определение фактического символа-разделителя
  4. Определение специальных символов (например, кавычки)

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

Поэтому лучшим подходом представляется телескопическое обнаружение, при котором форматы, которые также могут быть классифицированы как CSV (например, форматы файлов журналов, такие как Apache CLF), рассматриваются до применения правил обнаружения CSV.

Даже коммерческие приложения, такие как Excel, похоже, полагаются на расширение файла (.csv) для принятия решения по (1), что, очевидно, не является автоопределением, хотя проблема значительно упрощается, если приложению сообщают, что данные являются CSV.

Вот несколько хороших статей, обсуждающих эвристику для (2) и (3):

Определение (4), типа кавычек, может быть основано на обработке нескольких строк из файла и поиске соответствующих значений (например, четное количество ' или " в строке означает одинарные или двойные кавычки). Такая обработка может быть выполнена путем инициализации существующего парсера CSV (например, OpenCSV), который будет должным образом заботиться о разделении строк CSV (например, многострочные события).

Но что насчет (1), т.е. принятия решения о том, что данные являются CSV?

Может ли data mining помочь в этом решении?

10
задан Community 23 May 2017 в 12:06
поделиться