Страницы

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

пятница, 12 апреля 2019 г.

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

Читаю txt-файлы в java/groovy в кодировке WINDOWS-1251
Часть файлов читается успешно, но один файл из читается успешно только под 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............|


Ответ

вы применили лишнюю перекодировку «из 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 путь.к.файлу

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

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