Поведение Java BufferedReader в файле CSV и TXT

Если я попытаюсь прочитать файл CSV с именем csv_file.csv. Проблема в том, что когда я читаю строки с BufferedReader.readLine(), он пропускает первую строку с месяцами. Но когда я переименовываю файл в csv_file.txt, он читает его нормально и не пропускает первую строку.

Есть ли недокументированная «функция» BufferedReader, о которой я не знаю?

Пример файла:

Months, SEP2010, OCT2010, NOV2010
col1, col2, col3, col4, col5
aaa,,sdf,"12,456",bla bla bla, xsaffadfafda
and so on, and so on, "10,00", xxx, xxx

Код:

FileInputStream stream = new FileInputStream(UploadSupport.TEMPORARY_FILES_PATH+fileName);
BufferedReader br = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
String line = br.readLine();
String months[] = line.split(",");
while ((line=br.readLine())!=null) {
    /*parse other lines*/
}

person Gabriel    schedule 03.01.2011    source источник
comment
Покажи свой код. BufferedReader ничего не знает о файле или имени файла, а только о содержимом, которое он читает из другого Reader.   -  person Mike Q    schedule 03.01.2011
comment
я обновил описание своего вопроса... и я знаю, что java не заботится об имени файла, но я получаю различное поведение для разных имен файлов   -  person Gabriel    schedule 03.01.2011
comment
Кажется надуманным, что изменение поведения связано с расширением. Как вы переименовываете файл (через переименование ОС или путем повторного сохранения в том же приложении или с помощью другого редактора)? Вероятно, потребуется некоторая дальнейшая отладка. Что произойдет, если вы измените расширение обратно на .csv? Что, если вы изначально сохраните файл с расширением .txt (из Excel)? Каково содержимое выброшенной строки?   -  person Bert F    schedule 03.01.2011
comment
Я меняю расширение в проводнике Windows, простое переименование файла. И если я верну его обратно в csv, он сделает то же самое, он перепрыгнет через первую строку. И я, честно говоря, понятия не имею, почему это происходит.   -  person Gabriel    schedule 03.01.2011
comment
Из какой библиотеки UploadSupport?   -  person Powerlord    schedule 03.01.2011
comment
Это может быть экстремально, но как насчет того, чтобы получить шестнадцатеричный дамп первых двух строк?   -  person Andrew White    schedule 03.01.2011
comment
UploadSupport — это мой собственный класс, который я создал, а TEMPORARY_FILES_PATH — константа.   -  person Gabriel    schedule 03.01.2011
comment
@Andrew White: я проверил оба файла и они идентичны ... символы новой строки одинаковы   -  person Gabriel    schedule 03.01.2011
comment
Не могли бы вы обновить свой пример и заменить br.readLine(); своим циклом? Причиной может быть неосторожное использование readLine. Например, while (br.readLine() != null) { String line = br.readLine();} будет пропускать каждую вторую строку.   -  person jt.    schedule 03.01.2011
comment
Очень интересно. Какая ОС? Какой тип файловой системы?   -  person Bert F    schedule 03.01.2011
comment
@jt: цикл while выполняется после того, как я прочитал первую строку, а после этого я перебираю остальные строки с помощью `while ((line=br.readLine())!=null){ /*делаем что-то*/ } но я обновлю его   -  person Gabriel    schedule 03.01.2011
comment
@Bert F: Windows 7 Ultimate 64-битная, файловая система NTFS.   -  person Gabriel    schedule 03.01.2011
comment
@Габриэль - Спасибо. Я разместил класс и мои результаты ниже. Хочешь попробовать?   -  person Bert F    schedule 03.01.2011


Ответы (4)


В общем, использование конструктора InputStreamReader(InputStream in), который использует "кодировку по умолчанию", является плохой практикой. Вы должны указать кодировку явно.

Однако это вряд ли может объяснить вашу проблему.

person leonbloy    schedule 03.01.2011

Нет разницы в моей системе:

  • Windows Vista с пакетом обновления 2 (32-разрядная версия)
  • NTFS
  • JDK 1.6.0_17

Выход:

Creating C:\workspace\Sandbox\src\data.txt

Reading C:\workspace\Sandbox\src\data.txt
Skipped: 'Months, SEP2010, OCT2010, NOV2010'
First read: 'col1, col2, col3, col4, col5'

Reading C:\workspace\Sandbox\src\data.csv
Skipped: 'Months, SEP2010, OCT2010, NOV2010'
First read: 'col1, col2, col3, col4, col5'

Reading C:\workspace\Sandbox\src\data.txt
Skipped: 'Months, SEP2010, OCT2010, NOV2010'
First read: 'col1, col2, col3, col4, col5'

Код:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;


public class BuffReadTest {

    public static void main(final String[] args) {
        final String baseFilename = args[0] + "/data";
        try {
            final File txtFile = new File(baseFilename+".txt");
            final File csvFile = new File(baseFilename+".csv");

            if (txtFile.exists())   txtFile.delete();
            if (csvFile.exists())   csvFile.delete();
            createFile(txtFile.getAbsolutePath());

            readFile(txtFile.getAbsolutePath());

            txtFile.renameTo(csvFile);
            readFile(csvFile.getAbsolutePath());

            csvFile.renameTo(txtFile);
            readFile(txtFile.getAbsolutePath());

        } catch (final IOException ex) {
            System.out.println("Exception: "+ex);
            ex.printStackTrace();
        }
    }

    private static void createFile(final String filename)
            throws FileNotFoundException {
        System.out.println("\nCreating "+filename);
        final PrintWriter pw = new PrintWriter(filename);
        pw.println("Months, SEP2010, OCT2010, NOV2010");
        pw.println("col1, col2, col3, col4, col5");
        pw.println("aaa,,sdf,\"12,456\",bla bla bla, xsaffadfafda");
        pw.println("and so on, and so on, \"10,00\", xxx, xxx");
        pw.close();
    }

    private static void readFile(final String filename)
            throws FileNotFoundException, IOException {
        System.out.println("\nReading "+filename);
        final FileInputStream stream = new FileInputStream(filename);
        final BufferedReader br = new BufferedReader(new InputStreamReader(stream));
        final String skipped = br.readLine();
        final String first = br.readLine();

        System.out.println("Skipped: '"+skipped+"'");
        System.out.println("First read: '"+first+"'");
        br.close();
    }

}
person Bert F    schedule 03.01.2011

Что ж, расширение файла файла игнорируется Java (на самом деле единственное, что обычно заботится о расширениях файлов, - это Windows). Я предполагаю, что у вас есть какая-то новая строка/очень тонкая проблема с кодированием, вызывающая проблему, которую вы видите.

person Andrew White    schedule 03.01.2011

Ваш редактор делает что-то особенное при сохранении файла? Вы работаете в Windows? (есть некоторые различия в новой строке между Linux и Windows, хотя я никогда не сталкивался с проблемами при использовании Java)

person ivy    schedule 03.01.2011
comment
Я использую eclipse в Windows 7, и у меня есть стандартная строка, заканчивающаяся CR LF. и файл csv был создан путем сохранения файла excel как файла csv... но я смотрю на него в блокноте ++, и в этом файле нет ничего странного - person Gabriel; 03.01.2011