opencsv, нельзя использовать значения с"

Я использую open csv для чтения CSV, который имеет только 2 столбца, например:

"valueA1","valueB of A1"
,"valueB of A1"
,"valueB of A1"
,"valueB of A1"
"valueA2","valueB of A2"
,"valueB of A2"
,"valueB of A2"
,"valueB of A2"

И так продолжается, пока все хорошо. У меня возникают проблемы, когда некоторые значения в столбце B содержат некоторые символы. Пример:

"valueA1","va"lueB" of A1"
,"valueB of A1"
,"valueB of A1"
,"valueB of A1"
"valueA2","valueB of A2"
,"valueB of A2"
,"valueB of A2"
,"valueB of A2"

Когда мой столбец B имеет что-то вроде " или даже, в некоторых случаях, : мой открытый csv теряет весь формат и вместо того, чтобы сказать, что моя следующая строка содержит 2 значения, он показывает мне сумасшедшие вещи, такие как 36, 48, и из-за этого теряется огромное количество контента.

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

Я использую простой конструктор

reader = new CSVReader(new FileReader(arquivo));

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

reader = new CSVReader(new FileReader(arquivo), ',','"');

Но результат был тот же, так как конструктор принимает только char я не могу сделать ","


person prabello    schedule 15.10.2014    source источник
comment
Вы должны избегать " в строковых литералах, прежде чем записывать их в CSV.   -  person Balázs Édes    schedule 15.10.2014
comment
@ bali182 bali182 Вы имеете в виду, введите файл и удалите все перед запуском csv? Но это также удалит определение полей csv.   -  person prabello    schedule 15.10.2014
comment
У вас csv неправильный формат. Свяжитесь с провайдером и попросите его исправить.   -  person talex    schedule 15.10.2014
comment
Что сказал @talex. Это синтаксическая ошибка в вашем CSV. Если пишешь сам, то экранируй, перед записью в файл, иначе попроси того, кто создал, чтобы поправил.   -  person Balázs Édes    schedule 15.10.2014
comment
Моя проблема в том, что этот csv создает другая компания, и это единственный способ предоставления информации, нет веб-сервиса или чего-то подобного. Мне нужно прочитать содержимое этого файла и сохранить в моей базе данных, нет ли способа обойти эту проблему?   -  person prabello    schedule 15.10.2014
comment
Спросите их о формате. Может быть, это не CSV, а какой-то другой формат, который просто похож   -  person talex    schedule 15.10.2014
comment
На самом деле это xls, я перехожу с xls на csv, они даже сказали, что я должен открывать файл только в excel (поскольку это xls), и просмотр файла - это точная ситуация, которую я показал в вопросе . Они сказали, что нет возможности изменить формат файла или его содержимое.   -  person prabello    schedule 15.10.2014
comment
Похоже, вы конвертируете это неправильно   -  person talex    schedule 15.10.2014
comment
@talex преобразование выглядит нормально, но то, что вы сказали, имеет смысл, я попытаюсь преобразовать, используя ¢ вместо моего разделителя, я посмотрю, сработает ли это, я не думаю, что столкнусь с ¢ внутри моего csv. Или вы бы предложили мне другой подход?   -  person prabello    schedule 15.10.2014
comment
CSV поддерживает экранирование. Я не знаю, как вы конвертируете, но строка a"b может быть представлена ​​​​как "a""b"   -  person talex    schedule 15.10.2014


Ответы (2)


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

valueA1,"va""lueB"" of A1"

(В этом примере разрешается, но не обязательно заключать в двойные кавычки «valueA1».) Поскольку вы сами создаете CSV-файл из XLS-файла, вам следует устранить проблему при преобразовании.

Excel 2007 делает это правильно, если вы сохраняете как «CSV (MS-DOS) (*.csv)». Я помню, что в старых версиях Excel был экран параметров CSV, с которым вам, возможно, придется поиграться.

person gatkin    schedule 15.10.2014

Сначала я бы еще поставил разделитель и кавычки явно. Вы сказали, что у вас проблема с ;.

CSVReader reader = new CSVReader(new FileReader(arquivo), ',', '\"');

Затем возникает ошибка данных: текстовое значение va"lueB" of A1, которое, например, Excel автоматически экранирует как: va""lueB"" of A1. Я не знаю, что CSVWriter сделал бы с двойной кавычкой.

Наименее инвазивным было бы исправление данных при чтении:

CSVReader reader = new CSVReader(new RepairingReader(new FileReader(arquivo)),
                                 ',', '\"', '\\');

Здесь я также указываю escape-символ для разделителя и кавычки.

CSVReader использует BufferedReader либо переданный, либо добавленный сам по себе, и вызывает readLine.

public class RepairingReader extends BufferedReader {

    public RepairingReader(Reader reader, int capacity) {
        super(reader, capacity);
    }

    public RepairingReader(Reader reader) {
        super(reader);
    }

    @Override
    public String readLine() throws IOException {
        String line = super.readLine();
        if (line != null) {
            line = line.replaceAll("([^,\\\\])\"([^,])", "$1\\\\\"$2");
        }
        return line;
    }
}

Это просто переопределяет readLine. Он заменяет любую цитату, перед которой стоит символ (не обратная косая черта, не запятая) и после (не запятая). Замена должна быть обратной косой чертой, за которой следует кавычка.

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

Кстати: FileReader не имеет возможности установить кодировку, используемую для преобразования файла в строку Unicode. Используется кодировка платформы по умолчанию. Значит код не переносимый, файл должен быть в локальной кодировке. Вместо этого используйте new InputStreamReader(new FileInputStream(file), encoding) для портативного программного обеспечения.

person Joop Eggen    schedule 15.10.2014