Porównanie wartości z pliku kodowanego w "1250 (ANSI - Europa Środkowa)" ze stałymi

0

Mam plik CSV, który jest kodowany w "1250 (ANSI - Europa Środkowa)" (informację uzyskałem z TEncoding.EncodingName, po załadowaniu pliku do TStrings).

Na wstępie do przetwarzania pliku CSV mam funkcję, która sprawdza strukturę pliku - polega to na porównaniu listy nazw kolumn z pliku z listą oczekiwanych nazw kolumn zapisanych w kodzie programu.

Kłopot pojawił się w momencie, kiedy w kolumnie pojawiły się polskie znaki. Wartość z pliku jest "z krzakami". Jak się je porównuje ze stałymi tekstowymi wychodzi niezgodność i plik nie jest dalej przetwarzany (uznajemy, że struktura pliku jest niepoprawna).

Jak to w ogóle ugryźć.

0

@toyman - tutaj kłopot sprawia na pewno kodowanie;

Spróbuj tę wartość z krzakami najpierw przekonwertować za pomocą funkcji coś w rodzaju Utf8ToAnsi, a dopiero później porównuj łańcuchy za pomocą np. funkcji AnsiCompareStr lub podobnych; Z tej wymienionej korzystam pod Lazarusem, w Delphi pewnie jest podobna;

Przed chwilą miałem dokładnie ten sam problem, tyle że literał ze znakami diakrytycznymi miał krzaki (sprawdzane pod debugerem), a nie łańcuchy z pliku; Konwersja przez wymienioną funkcję była rozwiązaniem problemu;

Być może plik ma nieprawidłowe kodowanie, skoro piszesz, że to właśnie zawartość pliku posiada krzaki; Jeśli nie masz pewności to skorzystaj z konwerterów kodowania plików - np. Notepad++ ma taką funkcję; Tylko nie przestawiaj kodowania, a użyj opcji konwersji do ANSI.

0

Muszę się poprawić - plik jest kodowany w UTF8. Kiedy robiłem TStrings.LoadFromFile podawałem tylko argument "FileName". Sprawdziłem programem zewnętrznym i wyszło, że plik ma kodowanie UTF8. Rozszerzyłem LoadFromFile o TStrings.LoadFromFile(FileName,TEncoding.UTF8) i krzaki zniknęły.

Porównanie ze stałymi tekstowymi jest teraz realizowane poprawnie.

0

Problem z niezgodnością stron kodowych objawił się kawałek dalej. Chodziło o to, że baza danych Oracle kodowana była w Win1250, a plik źródłowy w UTF8. Po załadowaniu danych do programu porównania wykonywane były poprawnie, ale na etapie wykonywania SQL - nie. Podgląd zmiennych podczas debugowania pokazywał, że zapytanie zostało ładnie skomponowane - zawierało poprawne polskie znaki, ale po przesłaniu do serwera nie wykonywało się poprawnie (SELECT zwracał niepoprawne dane - niekompletny zbiór). Skopiowanie treści zapytania SQL z podglądu zmiennych, wklejenie i uruchomienie w PL\SQL Developerze dawało poprawne wyniki.

Problem rozwiązałem w ten sposób, że na etapie ładowania pliku, od razu wykonywana jest sztywna konwersja UTF8 -> WIN1250 i całość działa teraz bez zarzutu.

Łyżką dziegciu w beczce miodu jest "sztywna konwersja UTF8->WIN1250" - polega to na tym, że muszę jawnie w programie ustawić Encoding źródłowy i docelowy przed załadowaniem danych, żeby mogła się dokonać prawidłowa konwersja.

Kopałem dość długo na Googlach i nie znalazłem sensownego kodu, który pozwalał by jednoznacznie określić kodowanie pliku ZANIM rozpocznie się właściwe ładowanie danych.

Chodzi o to, że używając TStrings.LoadFromFile musze jawnie z góry określić format kodowania pliku, który ładuję. W przeciwnym wypadku automatycznie zostanie ustawione Encoding.Default - co oznacza WinACP (Actual Code Page systemu operacyjnego) = WIN1250. Plik jest w UTF8, więc załadują się krzaki.

Chciałbym osiągnąć taki efekt, że niezależnie w jakim kodowaniu klient dostarczy mi plik - kodowanie zostanie rozpoznane, plik załadowany z tym kodowaniem, a następnie skonwertowany do kodowania zgodnego z bazą danych, z którą aplikacja jest połączona.

Jeżeli chodzi o określenie strony kodowej bazy danych, to jest to dość proste:

SELECT value$ FROM sys.props$ WHERE name = 'NLS_CHARACTERSET' ; 

Nie umiem sobie poradzić ze stroną kodową ładowanego pliku.

0 użytkowników online, w tym zalogowanych: 0, gości: 0