Подтвердить что ты не робот

Чтение CSV со сканером()

Мой csv читается в System.out, но я заметил, что любой текст с пробелом перемещается в следующую строку (как return\n)

Вот как начинается мой csv:

first,last,email,address 1, address 2
john,smith,[email protected],123 St. Street,
Jane,Smith,[email protected],4455 Roger Cir,apt 2

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

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

public class main {

    public static void main(String[] args) {
        // -define .csv file in app
        String fileNameDefined = "uploadedcsv/employees.csv";
        // -File class needed to turn stringName to actual file
        File file = new File(fileNameDefined);

        try{
            // -read from filePooped with Scanner class
            Scanner inputStream = new Scanner(file);
            // hashNext() loops line-by-line
            while(inputStream.hasNext()){
                //read single line, put in string
                String data = inputStream.next();
                System.out.println(data + "***");

            }
            // after loop, close scanner
            inputStream.close();


        }catch (FileNotFoundException e){

            e.printStackTrace();
        }

    }
}

Итак, вот результат в консоли:

first,last,email,address 
1,address 
2
john,smith,[email protected],123 
St. 
Street,
Jane,Smith,[email protected],4455 
Roger 
Cir,apt 
2

Я неправильно использую сканер?

4b9b3361

Ответ 1

scanner.useDelimiter(",");

Это должно работать.

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


public class TestScanner {

    public static void main(String[] args) throws FileNotFoundException {
        Scanner scanner = new Scanner(new File("/Users/pankaj/abc.csv"));
        scanner.useDelimiter(",");
        while(scanner.hasNext()){
            System.out.print(scanner.next()+"|");
        }
        scanner.close();
    }

}

Для файла CSV:

a,b,c d,e
1,2,3 4,5
X,Y,Z A,B

Выход:

a|b|c d|e
1|2|3 4|5
X|Y|Z A|B|

Ответ 2

Пожалуйста, прекратите писать ошибочные парсеров CSV!

Я видел сотни парсеров CSV и так называемые обучающие программы для них в Интернете.

Почти каждый из них ошибается!

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

Пожалуйста, имейте в виду, что CSV (в порядке увеличения не столь очевидности):

  • может содержать символы вокруг значений
  • могут иметь другие цитирующие символы, чем
  • могут даже иметь другие символы цитирования, чем "и"
  • может вообще не содержать кавычек
  • может даже указывать символы на некоторые значения, а другие - на других
  • могут иметь другие разделители, чем, и;
  • может иметь пробелы между разделителями и (кавычками) значениями
  • может иметь другие кодировки, чем ascii
  • должно иметь одинаковое количество значений в каждой строке, но не всегда
  • может содержать пустые поля, либо процитированные: "foo","","bar", либо нет: "foo",,"bar"
  • может содержать символы новой строки в значениях
  • не может содержать символы новой строки в значениях, если они не ограничены
  • не может содержать символы новой строки между значениями
  • может иметь разделительный символ внутри значения, если он экранирован надлежащим образом
  • не использует обратную косую черту для исключения разделителей, но...
  • использует сам символ цитирования, чтобы избежать его, например. Frodo Ring будет 'Frodo' Ring'
  • может иметь символ цитирования в начале или конце значения или даже как только символ ("foo""", """bar", """")
  • может даже иметь цитируемый символ в пределах не котируемого значения; это не ускользнуло

Если вы считаете, что это явно не проблема, подумайте еще раз. Я видел, как каждый из этих элементов реализован неправильно. Даже в основных пакетах программного обеспечения. (например, Office-Suites, CRM Systems)

Есть хорошие и правильно работающие готовые читатели и писатели CSV:

Если вы настаиваете на написании своего, по крайней мере, прочитайте (очень короткий) RFC для CSV.

Ответ 3

Scanner.next() не читает новую строку, но читает следующий токен, помеченный пробелом (по умолчанию, если useDelimiter() не использовался для изменения шаблона разделителя). Для чтения строки используйте Scanner.nextLine().

Как только вы прочтете одну строку, вы можете использовать String.split(",") для разделения строки на поля. Это позволяет идентифицировать строки, которые не состоят из необходимого количества полей. Использование useDelimiter(","); игнорирует линейную структуру файла (каждая строка состоит из списка полей, разделенных запятой). Например:

while (inputStream.hasNextLine())
{
    String line = inputStream.nextLine();
    String[] fields = line.split(",");
    if (fields.length >= 4) // At least one address specified.
    {
        for (String field: fields) System.out.print(field + "|");
        System.out.println();
    }
    else
    {
        System.err.println("Invalid record: " + line);
    }
}

Как уже упоминалось, рекомендуется использовать библиотеку CSV. Во-первых, это (и useDelimiter(",") решение) неправильно обрабатывает цитируемые идентификаторы, содержащие символы ,.

Ответ 4

Если вы абсолютно должны использовать Scanner, вы должны установить его разделитель с помощью метода useDelimiter(...). Иначе он по умолчанию будет использовать все пробелы в качестве разделителя. Лучше, хотя, как уже было сказано, используйте библиотеку CSV, так как это то, что они делают лучше всего.

Например, этот разделитель будет разделен запятыми с окружающим пробелом или без него:

scanner.useDelimiter("\\s*,\\s*");

Подробнее об этом можно узнать в java.util.Scanner API.

Ответ 5

package take;

public class DateUtil {

// List of all date formats that we want to parse.
// Add your own format here.
private static List<SimpleDateFormat> 
        dateFormats = new ArrayList<SimpleDateFormat>() {
    private static final long serialVersionUID = 1L; 
    {
        add(new SimpleDateFormat("M/dd/yyyy"));
        add(new SimpleDateFormat("dd.M.yyyy"));
        add(new SimpleDateFormat("M/dd/yyyy hh:mm:ss a"));
        add(new SimpleDateFormat("dd.M.yyyy hh:mm:ss a"));
        add(new SimpleDateFormat("dd.MMM.yyyy"));
        add(new SimpleDateFormat("dd-MMM-yyyy"));
    }
};

/**
 * Convert String with various formats into java.util.Date
 * 
 * @param input
 *            Date as a string
 * @return java.util.Date object if input string is parsed 
 *          successfully else returns null
 */
public static Date convertToDate(String input) {
    Date date = null;
    if(null == input) {
        return null;
    }
    for (SimpleDateFormat format : dateFormats) {
        try {
            format.setLenient(false);
            date = format.parse(input);
        } catch (ParseException e) {
            //Shhh.. try other formats
        }
        if (date != null) {
            break;
        }
    }

    return date;
}

}

Ответ 6

Ну, я делаю свое кодирование в NetBeans 8.1:

Сначала: создайте новый проект, выберите приложение Java и назовите свой проект.

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

/**
 * @param args the command line arguments
 * @throws java.io.FileNotFoundException
 */
public static void main(String[] args) throws FileNotFoundException {
    try (Scanner scanner = new Scanner(new File("C:\\Users\\YourName\\Folder\\file.csv"))) {
         scanner.useDelimiter(",");
         while(scanner.hasNext()){
             System.out.print(scanner.next()+"|");
         }}
    }
}