Файл чтения Java получил ведущую спецификацию [ï »¿] - PullRequest
5 голосов
/ 09 июня 2011

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

sony
sony

, обрабатывается только первый.но проблема в том, что Java не рассматривает их как равные.

INFO: [, s, o, n, y]
INFO: [s, o, n, y]

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

    FileReader fileReader = new FileReader("some_file.txt");
    BufferedReader bufferedReader = new BufferedReader(fileReader);
    String prevLine = "";
    String strLine
    while ((strLine = bufferedReader.readLine()) != null) {
        logger.info(Arrays.toString(strLine.toCharArray()));
        if(strLine.contentEquals(prevLine)){
            logger.info("Skipping the duplicate lines " + strLine);
            continue;
        }
        prevLine = strLine;
    }

Обновление:

Кажется, в первой строке есть пробел, но на самом деле это не так, и подход trim не работает для меня.Они не одинаковы:

INFO: [, s, o, n, y]
INFO: [ , s, o, n, y]

Я не знаю, какой первый Char добавлен Java.

Решено: проблема была решена с помощью Решение BalusC Спасибо, что указали на проблему спецификации, которая помогла мне быстро найти решение.

Ответы [ 6 ]

1 голос
/ 09 июня 2011

Попробуйте обрезать пробелы в начале и конце прочитанных строк.Просто замените ваше время на:

while ((strLine = bufferedReader.readLine()) != null) {
        strLine = strLine.trim();
        logger.info(Arrays.toString(strLine.toCharArray()));
    if(strLine.contentEquals(prevLine)){
        logger.info("Skipping the duplicate lines " + strLine);
        continue;
    }
    prevLine = strLine;
}
0 голосов
/ 01 февраля 2018

Метка порядка байтов ( BOM ) - это символ Unicode.Вы получите символы, такие как  в начале текстового потока, потому что Использование спецификации является необязательным, и, если используется, должно появляться в начале текстаstream .

  • Компиляторы и интерпретаторы Microsoft, а также множество программ для Microsoft Windows, таких как Блокнот, обрабатывают спецификацию как необходимое магическое число а не использовать эвристику.Эти инструменты добавляют спецификацию при сохранении текста как UTF-8 и не могут интерпретировать UTF-8, если эта спецификация не присутствует или файл содержит только ASCII.Документы Google также добавляют спецификацию при преобразовании документа в простой текстовый файл для загрузки.
File file = new File( csvFilename );
FileInputStream inputStream = new FileInputStream(file);
// [{"Key2":"21","Key1":"11","Key3":"31"} ]
InputStreamReader inputStreamReader = new InputStreamReader( inputStream, "UTF-8" );

Мы можем решить, явно указав кодировку как UTF-8 для InputStreamReader.Затем в UTF-8 последовательность байтов  декодируется в один символ, который является U + FEFF (?).

ИспользованиеGoogle Guava's jar CharMatcher , вы можете удалить любые непечатаемые символы и затем сохранить все символы ASCII (удаляя любые акценты) как this :

String printable = CharMatcher.INVISIBLE.removeFrom( input );
String clean = CharMatcher.ASCII.retainFrom( printable );

Полный пример для чтения данных из файла CSV в объект JSON :

public class CSV_FileOperations {
    static List<HashMap<String, String>> listObjects = new ArrayList<HashMap<String,String>>();
    protected static List<JSONObject> jsonArray = new ArrayList<JSONObject >();

    public static void main(String[] args) {
        String csvFilename = "D:/Yashwanth/json2Bson.csv";

        csvToJSONString(csvFilename);
        String jsonData = jsonArray.toString();
        System.out.println("File JSON Data : \n"+ jsonData);
    }

    @SuppressWarnings("deprecation")
    public static String csvToJSONString( String csvFilename ) {
        try {
            File file = new File( csvFilename );
            FileInputStream inputStream = new FileInputStream(file);

            String fileExtensionName = csvFilename.substring(csvFilename.indexOf(".")); // fileName.split(".")[1];
            System.out.println("File Extension : "+ fileExtensionName);

            // [{"Key2":"21","Key1":"11","Key3":"31"} ]
            InputStreamReader inputStreamReader = new InputStreamReader( inputStream, "UTF-8" );

            BufferedReader buffer = new BufferedReader( inputStreamReader );
            Stream<String> readLines = buffer.lines();
            boolean headerStream = true;

            List<String> headers = new ArrayList<String>();
            for (String line : (Iterable<String>) () -> readLines.iterator()) {
                String[] columns = line.split(",");
                if (headerStream) {
                    System.out.println(" ===== Headers =====");

                    for (String keys : columns) {
                        //  - UTF-8 - ? « https://stackoverflow.com/a/11021401/5081877
                        String printable = CharMatcher.INVISIBLE.removeFrom( keys );
                        String clean = CharMatcher.ASCII.retainFrom(printable);
                        String key = clean.replace("\\P{Print}", "");
                        headers.add( key );
                    }
                    headerStream = false;
                    System.out.println(" ===== ----- Data ----- =====");
                } else {
                    addCSVData(headers, columns );
                }
            }
            inputStreamReader.close();
            buffer.close();


        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    @SuppressWarnings("unchecked")
    public static void addCSVData( List<String> headers, String[] row ) {
        if( headers.size() == row.length ) {
            HashMap<String,String> mapObj = new HashMap<String,String>();
            JSONObject jsonObj = new JSONObject();
            for (int i = 0; i < row.length; i++) {
                mapObj.put(headers.get(i), row[i]);
                jsonObj.put(headers.get(i), row[i]);
            }
            jsonArray.add(jsonObj);
            listObjects.add(mapObj);
        } else {
            System.out.println("Avoiding the Row Data...");
        }
    }
}

json2Bson.csv Файл данных.

Key1    Key2    Key3
11  21  31
12  22  32
13  23  33
0 голосов
/ 09 июня 2011

У меня был похожий случай в моем предыдущем проекте.Виновником была метка порядка байтов , от которой мне пришлось избавиться.В конце концов я реализовал взлом на основе этого примера .Проверьте это, возможно, у вас такая же проблема.

0 голосов
/ 09 июня 2011

Какая кодировка файла?

Невидимым символом в начале файла может быть Порядок следования байтов

Сохранение с использованием ANSI или UTF-8 без спецификации может помочь выделить это для вас.

0 голосов
/ 09 июня 2011

В начале должен быть space или какой-либо непечатный символ.Итак, либо исправьте это, либо обрежьте Strings во время / перед сравнением.

[Отредактировано]

В случае, если String.trim() бесполезно.Попробуйте String.replaceAll(), используя правильный regex.Попробуйте это, str.replaceAll("\\p{Cntrl}", "").

0 голосов
/ 09 июня 2011

Если пробелы не важны при обработке, вероятно, в любом случае стоило бы делать вызов strLine.trim() каждый раз.Это то, что я обычно делаю при обработке ввода, как это - пробелы могут легко заползти в файл, если его нужно редактировать вручную, и если они не важны, их можно и нужно игнорировать.

Редактировать: этофайл в кодировке UTF-8?Возможно, вам придется указать кодировку при открытии файла.Это может быть метка порядка байтов или что-то в этом роде, если это происходит в первой строке.

Попробуйте:

BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF8"))
...