Страницы

Поиск по вопросам

суббота, 8 февраля 2020 г.

Проблема с кодировкой windows-1251 на linux

#java #linux #кодировка #groovy


Читаю txt-файлы в java/groovy в кодировке WINDOWS-1251.

Часть файлов читается успешно, но один файл из 1С читается успешно только под windows,
а под linux кодировка обрабатывается неверно. 

Код чтения из файла Groovy

  String fileEncoding = "cp1251"
  file.eachLine(fileEncoding) { line -> esvData << line.split('=')
    System.out.println(line)}


В логе на Windows видны русские буквы, а на i686-redhat-linux(6.0) лог имеет следующий вид:


  1CClientBankExchange
  ВерсияФормата=1.02
  РљРѕРґРёСЂРѕРІРєР°=Windows
  Отправитель=
  Получатель=
  ДатаСоздания=23.03.2015
  ВремяСоздания=01:46:15
  ДатаНачала=20.03.2015
  ДатаКонца=20.03.2015
  РасчСчет=407028


При этом файлы в кодировке windows-1251 из других источников обрабатываются успешно
на том же linux.

В чем-то, кроме кодировки, может быть разница? Слышал, что могут присутствовать какие-то
доп. символы в начале файла.

package com.peterservice.pays.filepay.camel.processors.inscriptproc;

import com.peterservice.pays.filepay.camel.processors.InScriptProc;
import com.peterservice.pays.filepay.enums.CamelProperties;
import com.peterservice.pays.filepay.enums.Directories;
import com.peterservice.pays.filepay.model.Pay;
import com.peterservice.pays.filepay.model.PayRoute;
import org.apache.camel.Exchange;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.impl.DefaultExchange;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;

import java.io.File;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by Yuriy.Vinogradov on 06.08.2015.
 */
public class InScriptProc1CTest {

    @Test
    public void test() throws Exception {
        InScriptProc processor = new InScriptProc();
        Exchange exchange = prepareExchange();
        processor.process(exchange);
        Pay[] payments = exchange.getIn().getBody(Pay[].class);
        Assert.assertEquals(256, payments.length);
        for (Pay payment : payments) {
            if (payment.number.equals("549")) {
                Assert.assertEquals(new BigDecimal("0.4"), payment.amount);
                Assert.assertEquals("2015-03-20", payment.inDate);
                Assert.assertEquals("770fgh320", payment.INN);
                Assert.assertEquals("770fhh001", payment.payerKpp);
                Assert.assertEquals("401058fgh000fh79", payment.payerAccount);
                Assert.assertEquals("УФК по г.Москве (ФКУ \"Дирекция космодрома \"Восточный\")",
payment.payerTitle);
                Assert.assertEquals("25904fgh2221 0373fg910 Опл.  за услуги сот.связи
за декабрь2014, дог.от 12.12.14  №2350948, сч.14-1 от 26.12.2014, акт  DV03/70761371/28
 от 26,12,2014 , в т.ч. НДС-0,06 (л/с 15fg925)", payment.paymentReason);
            } else if(payment.number.equals("701")) {
                Assert.assertEquals(new BigDecimal("1.79"), payment.amount);
                Assert.assertEquals("2015-03-20", payment.inDate);
                Assert.assertEquals("2815fff915", payment.INN);
                Assert.assertEquals("27fff1001", payment.payerKpp);
                Assert.assertEquals("30302810fffh0000100", payment.payerAccount);
                Assert.assertEquals("ФКП \"Аэропорты Дальнего Востока\" р/с 40502810409fghfh001
в ХФ ОАО \"МДМ БАНК\"  г Хабаровск", payment.payerTitle);
                Assert.assertEquals("УИНО///Оплата по сч-фак. №10010687719/800 от
28.02.2015 л/счет 1fgh4543. Сумма 1-79 В т.ч. НДС  (18%) 0-27", payment.paymentReason);
            } else if(payment.number.equals("822")) {
                Assert.assertEquals(new BigDecimal("50"), payment.amount);
            }else{
           //     Assert.fail("Not expected document number:" + payment.number +
" Check if it is correct and create if branch for this document number");
            }
        } 
    }

    private Exchange prepareExchange() {
        Exchange exchange = new DefaultExchange(new DefaultCamelContext());
        PayRoute payRoute = new PayRoute();
        exchange.getIn().setBody(payRoute);
        payRoute.setInScript("src/scripts/1c-java.groovy");
        Map resultDirs = new HashMap<>();
        resultDirs.put(Directories.ERROR.title, "test/" + Directories.ERROR.title
+ "/dir/");
        resultDirs.put(Directories.GF.title, "test/" + Directories.GF.title + "/dir/");
        resultDirs.put(Directories.LG.title, "test/" + Directories.LG.title + "/dir/");
        resultDirs.put(Directories.UNDEFINED.title, "test/" + Directories.GF.title
+ "/dir/");
        resultDirs.put(Directories.LOG.title, "test/" + Directories.LOG.title + "/dir/");
        payRoute.setResultDirs(resultDirs);
        exchange.setProperty(CamelProperties.ProcessingFile.title, new File("src/test/resources/sberbank_27_20150320_1.txt").getAbsoluteFile());
        return exchange;
    }
}


hexdump  для проверки начала файла на bom

[relstand@srv3-amain-a test]$ hexdump -C sberbank_27_20150320_1.txt | head
00000000  31 43 43 6c 69 65 6e 74  42 61 6e 6b 45 78 63 68  |1CClientBankExch|
00000010  61 6e 67 65 0d 0a c2 e5  f0 f1 e8 ff d4 ee f0 ec  |ange............|

    


Ответы

Ответ 1



вы применили лишнюю перекодировку «из cp1251 в utf8», в чём несложно убедиться, выполнив обратную перекодировку: $ echo '1CClientBankExchange ВерсияФормата=1.02 РљРѕРґРёСЂРѕРІРєР°' | iconv -f utf8 -t cp1251 1CClientBankExchange ВерсияФормата=1.02 Кодировка читайте этот файл «как есть», без каких-либо перекодировок. Слышал, что могут присутствовать какие-то доп символы в начале файла? да, это называется bom. убедиться в их наличии/остутствии можно, например, так: $ hexdump -C путь.к.исследуемому.файлу | head 00000000 70 61 63 6b 61 67 65 20 63 6f 6d 2e 70 65 74 65 |package com.pete| 00000010 72 73 65 72 76 69 63 65 2e 70 61 79 73 2e 66 69 |rservice.pays.fi| 00000020 6c 65 70 61 79 2e 63 61 6d 65 6c 2e 70 72 6f 63 |lepay.camel.proc| 00000030 65 73 73 6f 72 73 2e 69 6e 73 63 72 69 70 74 70 |essors.inscriptp| 00000040 72 6f 63 3b 0a 0a 69 6d 70 6f 72 74 20 63 6f 6d |roc;..import com| 00000050 2e 70 65 74 65 72 73 65 72 76 69 63 65 2e 70 61 |.peterservice.pa| 00000060 79 73 2e 66 69 6c 65 70 61 79 2e 63 61 6d 65 6c |ys.filepay.camel| 00000070 2e 70 72 6f 63 65 73 73 6f 72 73 2e 49 6e 53 63 |.processors.InSc| 00000080 72 69 70 74 50 72 6f 63 3b 0a 69 6d 70 6f 72 74 |riptProc;.import| 00000090 20 63 6f 6d 2e 70 65 74 65 72 73 65 72 76 69 63 | com.peterservic| обновление а ещё парсер, теоретически, может «сбиваться» из-за разных окончаний строк. распространённых вариантов как минимум три: cr lf cr + lf для изменения этих символов в операционной системе gnu/linux можно воспользоваться программами (из пакета dos2unix, присутствующего в репозиториях всех популярных дистрибутивов): dos2unix unix2dos unix2mac mac2unix вызов (для замены пары cr + lf на lf): $ dos2unix путь.к.файлу

Ответ 2



Это не win-1251. Так выглядит Юникод, ошибочно принятый за win-1251. Вот вам картинка-подсказка по распознаванию кодировок: https://hsto.org/files/d77/1c6/054/d771c60540c44bc984641c337fd099f0.png

Комментариев нет:

Отправить комментарий