Чтение файлов csv с помощью java (se8)

Я хочу использовать следующий код для извлечения данных из набора данных в файле csv:

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class ReadingCSVFiles {

public static void main(String[] args) {

    File dataFile = new File("URL\Countries.csv");
    try {
        @SuppressWarnings("resource")
        Scanner input = new Scanner(dataFile);
        input.useDelimiter(",|\\s");
        String column1 = input.next();
        String column2 = input.next();
        System.out.printf("%-11s%12s%n", column1, column2);
        while (input.hasNext()) {
            String Country = input.next();
            int Population = input.nextInt();
            System.out.printf("%-11s%, 12d%n", Country, Population);
            }

} catch (FileNotFoundException e) {
    System.out.println(e);
}
}
}

К сожалению, на выходе я получаю только первую строку:

Country           Population

Затем я получаю следующую ошибку:

Exception in thread "main" java.util.InputMismatchException
    at java.util.Scanner.throwFor (Unknown Source)
    at ...

Вот файл csv.file:

Country,Population
Argentina,41343201
Brazil,201103330
Chile,16746491
Columbia,47790000
Paraguay,6375830
Peru,29907003
Venezuela,27223228

Будем очень благодарны любой помощи.

Ваша первая строка имеет формат String, String, а не String, Number. Может быть, это ваша основная проблема?

Joseph Larson 10.08.2018 17:30

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

zhh 10.08.2018 17:31
0
2
148
4

Ответы 4

Используйте CSV-файл Apache Commons. Если это в дидактических целях, я думаю, вам нужен еще один звонок в next().

Вы устанавливаете разделитель на , или \s, который соответствует только одному символу пробела.

Если окончания файлов разделены двумя символами (как по умолчанию в системах Windows), например \r\n, он будет использовать только первый символ (\r), то есть следующий токен будет пустой строкой (считанной в Country), а токен после этого будет следующим названием страны, которое не может быть прочитано как int.

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

Это было почти правильно.

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class ReadingCSVFiles {
    public static void main(String[] args) {
        File dataFile = new File("URL\\Countries.csv");
        // the resources MUST be closed! Do not suppress these kind of warnings!
        try (Scanner input = new Scanner(dataFile)) {
            // what you forget is the newline: at the end of the lines, there maybe more than one white space character (on windows,\r\n)
            input.useDelimiter(",|\\s+");
            String column1 = input.next();
            String column2 = input.next();
            System.out.printf("columns: %-11s%12s%n", column1, column2);
            while (input.hasNextLine()) {
                String Country = input.next();
                int Population = input.nextInt();
                System.out.printf("%-11s%, 12d%n", Country, Population);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

В чем разница?

Steve Smith 10.08.2018 17:48

Самым важным различием был знак + в useDelimiter: "input.useDelimiter (", | \\ s + ");", еще одна вещь - инструкция try-with-resources, чтобы однозначно закрыть сканер в конце обработки.

m4gic 24.08.2018 11:49

вы можете использовать opencsv lib http://opencsv.sourceforge.net/, просто создайте DTO, например

 public class CountryAndPopulationDTO implements Serializable{

 private String country ;
 private String population;

 // getter & setter 
 }

// in your main

FileReader filereader = new FileReader(dataFile);
CSVReader reader = new CSVReader(filereader, ',');
Map<String, String> columnMapping = new HashMap<String, String>();

columnMapping.put("country", "country");
columnMapping.put("population", "population");

HeaderColumnNameTranslateMappingStrategy<CountryAndPopulationDTO> strategy = new HeaderColumnNameTranslateMappingStrategy<CountryAndPopulationDTO>();
strategy.setType(CountryAndPopulationDTO.class);
strategy.setColumnMapping(columnMapping);
List<CountryAndPopulationDTO> countryAndPopulationDTOList= new ArrayList<CountryAndPopulationDTO>();
try {
CsvToBean<CountryAndPopulationDTO> csv = new CsvToBean<CountryAndPopulationDTO>() {
    protected Object convertValue(String value, PropertyDescriptor prop) throws InstantiationException, IllegalAccessException {
        if (StringUtils.isEmpty(value)) {
            value = null;
        }
        return super.convertValue(value, prop);
    }
};
log.info(" -----------------  MAPPING CSV FILE  ----------------------------");
countryAndPopulationDTOList = csv.parse(strategy, reader); 

}catch (Exception e) {
 throw new Exception("Mapping problem --> ", e.getCause());
}

// Теперь у countryAndPopulationDTOList есть все ваши данные :)

Также можно использовать Commons CSV.

m4gic 10.08.2018 18:04

univocity-parsers превосходит их всех и работает в 3 раза быстрее.

Jeronimo Backes 15.08.2018 00:08

Другие вопросы по теме