Delphi5 ja UTF-8

HighwayPatrol

Miten D5:lla saa kirjoitettu merkistön UTF-8 mukaisia tiedostoja?

13

951

    Vastaukset

    Anonyymi (Kirjaudu / Rekisteröidy)
    5000
    • ASCII - koodaus

      Käsittääkseni Delphi 5 käyttää 8-bittistä windowsin merkkikoodausta. Kyseinen koodaus pohjautuu ASCII-koodaukseen. UTF-8 koodaus käyttää vaihtuvan pituista koodausta mutta sekin pohjautuu ASCII-koodaukseen. Eli kummankin koodauksen pohjalla on ASCII-koodaus.

      Katso ascii taulukko
      http://wiki.lazarus.freepascal.org/ASCII

      Tämä tarkoittaa sitä että 127 "alinta" merkkiä vastaavat toisiaan.

      Joudut muuttamaan vain merkit jotka ovat arvoltaan yli 127:n

      if ord(muunnettavat_merkit[merkin_paikka]) > 127 then

      Eli jos vastaan tulee 8-bittisen merkistön
      - Ä niin sen arvo korvautuu kahdella tavulla $C3 ja $84 ($ merkitsee heksa esitystä) eli desimaalisena 195 ja 132
      - Å $C3 ja $85 eli 195 ja 133
      - Ö $C3 ja $96 eli 195 ja 150
      - ä $C3 ja $A4 eli 195 ja 164
      - å $C3 ja $A5 eli 195 ja 165
      - ö $C3 ja $B6 eli 195 ja 182

      Kuten huomasit niin UTF-8 koodaus vie enemmän tilaa kuin 8-bittinen koodaus kun käytössä on muita kuin ASCII merkkejä. UTF-8 etuna on se että sillä pystytään esittämään kaikki merkit.

      • eurolla

        Euron merkki vaatii jo kolme tavua UTF-8 koodauksessa
        $E2 $82 $AC on desimaalisena 226, 130 ja 172


    • KAlle vaan

      > Miten D5:lla saa kirjoitettu merkistön UTF-8 mukaisia tiedostoja?

      Vähän turhan ylimalkainen oli kysymyksesi. Kannattaisi kertoa _tarkalleen_ että millaista operaatiota olet yrittelemässä. Useinhan nämä liittyvät mm. XML:ään tai johonkin muuhun specifiseen probleemaan, kenties kiinan Kanji-merkistöjen esitykseen jne.

      Sait jo yhden vinkin millä handlata simppeline suomalaisten ääkkösmerkkien korvaaminen UTF-vastineilla. Mutta ei tällainen koodaus vaikka johonkin tekstitiedostoon vielä jätä tietoa että tämä tekstitiedosto muuten nyt on sitten UTF-8 koodattua tiedostoa.
      Esim.HTML:ssä ja XML:ssä headerit kertovat kulloinkin käytetyn koodaustavan.

      Katsele vaikka onko tästä 20 USD hintaisesta toolsetistä mitään apuja ongelmaasi.
      http://www.delphipages.com/comp/diunicode_3_2-5050.html

      Ja ensi kerralla KERRO PALJON TARKEMMIN mitä oikein olet yrittämässä tehdä.

    • HighwayPatrol

      Tarve olisi tulostaa tiedostoksi sepa-maksuaineisto, joka lähetetään pankkiohjelmalla maksettavaksi. Laitan tämän viestin alle esimerkin viitteellisestä maksusta (kysymyksessä on kuitenkin viestillinen maksuaineisto).

      Netistä löysin tällaisen esimerkin:

      http://www.delphipages.com/forum/showthread.php?t=200627

      const
      Utf8ByteOrderMark=#$EF#$BB#$BF;
      procedure WriteWideString(FilePath:string;x:WideString);
      var
      f:TFileStream;
      begin
      f:=TFileStream.Create(FilePath,fmCreate);
      try
      f.Write(Utf8ByteOrderMark,3);
      f.Write(x[1],Length(x)*2);
      finally
      f.Free;
      end;
      end;

      • HighwayPatrol

        Esimerkin lähde: https://www.op.fi/media/liitteet?cid=150261694&srcpl=3.

        Esimerkki.


        OP-KESKUS LIITTYMÄKUVAUS 99
        Maksuliikepalvelut
        __________________________________________________
        OPK PIDÄTTÄÄ ITSELLÄÄN OKEUDEN MUUTOKSIIN
        10.3. Esimerkkisanomia
        10.3.1. SEPA-maksu viitteellä






        String
        2001-12-17T09:30:47.0Z
        false
        1
        100.5
        MIXD

        Aineiston tekijän nimi



        12354678901234567890
        TRF


        SEPA


        2009-05-13

        Maksajan nimi

        Osoiterivi 1
        Osoiterivi 2
        FI



        001234567





        FI9858499920000101




        OKOYFIHH


        SLEV


        9834894389743987


        NORM


        100.5



        NDEAFIHH



        Maksun saajan nimi

        Osoiterivi 1
        Osoiterivi 2
        FI




        FI2112345600000785






        SCOR

        00000000000000001245


      • HighwayPatrol
        HighwayPatrol kirjoitti:

        Esimerkin lähde: https://www.op.fi/media/liitteet?cid=150261694&srcpl=3.

        Esimerkki.


        OP-KESKUS LIITTYMÄKUVAUS 99
        Maksuliikepalvelut
        __________________________________________________
        OPK PIDÄTTÄÄ ITSELLÄÄN OKEUDEN MUUTOKSIIN
        10.3. Esimerkkisanomia
        10.3.1. SEPA-maksu viitteellä






        String
        2001-12-17T09:30:47.0Z
        false
        1
        100.5
        MIXD

        Aineiston tekijän nimi



        12354678901234567890
        TRF


        SEPA


        2009-05-13

        Maksajan nimi

        Osoiterivi 1
        Osoiterivi 2
        FI



        001234567





        FI9858499920000101




        OKOYFIHH


        SLEV


        9834894389743987


        NORM


        100.5



        NDEAFIHH



        Maksun saajan nimi

        Osoiterivi 1
        Osoiterivi 2
        FI




        FI2112345600000785






        SCOR

        00000000000000001245

        Op:n pdf:n sivulta 99 sivulle 101 löytyy tuo esimerkki.


      • snaju.2

        > Tarve olisi tulostaa tiedostoksi sepa-maksuaineisto, joka lähetetään pankkiohjelmalla
        > maksettavaksi. Laitan tämän viestin alle esimerkin viitteellisestä maksusta (kysymyksessä
        > on kuitenkin viestillinen maksuaineisto).

        Tuohan on normaalia ASCII-merkistöä sisältävä XML-tiedosto, ei siinä ole ainoatakaan 2:lla bytellä esitettyä UTF-merkkiä joukossa.

        Mitä tarkoitat "tulostaa tiedostoksi", kun tuohan on jo valmis XML-tiedosto, jonka pankkiohjelma vain kuskaa PC:ltä pankkiin.
        Tietenkin se XML-tiedosto voi olla yhtenä ainoana pötkönä, ilman ainoatakaan rivinvaihtomerkkejä, ja se näyttää aika vaikeaselkoiselta. Ja tämän mahdollisesti haluaisit pätkiä A4:lle mahtuviksi riveiksi?

        Vaikkapa IE-selain, tai tarkemmin selaimen sisäisesti kutsuma MSXML.DLL systeemitiedosto osaa avata tällaisen pötkörivisen XML-tiedostonkin, ja esittää sen ruudulla tuon OP-dokumentin esittämässä ihmisen luettavassa muodossa.

        Selostuksiasi en täysin tarkkaan ymmärrä, mutta saattaa olla että ongelmasi liittyvät XML-tiedostojen käsittelyyn, eivätkä niinkään UTF-tiedostojen luomiseen.

        EU:n SEPA-maksutiedostot on muutenkin määritelty niin, että vaikka otsikossa maailmanlaajuisen yhteensopivuuden vuoksi merkistönä mainitaan UTF-8, niin silti SEPA:ssa käytettävä merkistö on rajoitettu ISO-8859-15 merkkeihin. Joten ei sieltyä XML:stä mitään kummaa abyteristä merkistöä ole vastaan tulossa.


      • HighwayPatrol
        snaju.2 kirjoitti:

        > Tarve olisi tulostaa tiedostoksi sepa-maksuaineisto, joka lähetetään pankkiohjelmalla
        > maksettavaksi. Laitan tämän viestin alle esimerkin viitteellisestä maksusta (kysymyksessä
        > on kuitenkin viestillinen maksuaineisto).

        Tuohan on normaalia ASCII-merkistöä sisältävä XML-tiedosto, ei siinä ole ainoatakaan 2:lla bytellä esitettyä UTF-merkkiä joukossa.

        Mitä tarkoitat "tulostaa tiedostoksi", kun tuohan on jo valmis XML-tiedosto, jonka pankkiohjelma vain kuskaa PC:ltä pankkiin.
        Tietenkin se XML-tiedosto voi olla yhtenä ainoana pötkönä, ilman ainoatakaan rivinvaihtomerkkejä, ja se näyttää aika vaikeaselkoiselta. Ja tämän mahdollisesti haluaisit pätkiä A4:lle mahtuviksi riveiksi?

        Vaikkapa IE-selain, tai tarkemmin selaimen sisäisesti kutsuma MSXML.DLL systeemitiedosto osaa avata tällaisen pötkörivisen XML-tiedostonkin, ja esittää sen ruudulla tuon OP-dokumentin esittämässä ihmisen luettavassa muodossa.

        Selostuksiasi en täysin tarkkaan ymmärrä, mutta saattaa olla että ongelmasi liittyvät XML-tiedostojen käsittelyyn, eivätkä niinkään UTF-tiedostojen luomiseen.

        EU:n SEPA-maksutiedostot on muutenkin määritelty niin, että vaikka otsikossa maailmanlaajuisen yhteensopivuuden vuoksi merkistönä mainitaan UTF-8, niin silti SEPA:ssa käytettävä merkistö on rajoitettu ISO-8859-15 merkkeihin. Joten ei sieltyä XML:stä mitään kummaa abyteristä merkistöä ole vastaan tulossa.

        Nyt tulostan ohjelmasta suoraan LMP-muotoisen tekstitiedoston, jonka lähetän pankkiohjelmalla eteenpäin. Tarkoitus olisi siis muuttaa lähtevä aineisto Sepa-muotoiseksi. Ei kai tagien tulostaminen koodista ole vaikeaa. Ongelmaksi voivat muodostua ääkköset esimerkiksi maksajan tai saajan nimessä.

        Osaan siis tulostaa ascii-muotoisen tekstitiedoston. Sitä en tiedä, tuleeko ääkkösistä ongelmaa. Oletan kuitenkin, että olisi parempi tulostaa UTF-8:na.


      • snaju.2
        HighwayPatrol kirjoitti:

        Nyt tulostan ohjelmasta suoraan LMP-muotoisen tekstitiedoston, jonka lähetän pankkiohjelmalla eteenpäin. Tarkoitus olisi siis muuttaa lähtevä aineisto Sepa-muotoiseksi. Ei kai tagien tulostaminen koodista ole vaikeaa. Ongelmaksi voivat muodostua ääkköset esimerkiksi maksajan tai saajan nimessä.

        Osaan siis tulostaa ascii-muotoisen tekstitiedoston. Sitä en tiedä, tuleeko ääkkösistä ongelmaa. Oletan kuitenkin, että olisi parempi tulostaa UTF-8:na.

        > Osaan siis tulostaa ascii-muotoisen tekstitiedoston. Sitä en tiedä, tuleeko
        > ääkkösistä ongelmaa.

        Kunhan ISO-8859-15 merkistöä laittelet, lähinnä ääkkösien osalta, etkä sekoa DOS-ajan ääkkösalueelle, niin Sepan XML-tiedoston tosiaan ihan täysin pure-Asciita.

        > Oletan kuitenkin, että olisi parempi tulostaa UTF-8:na.

        Eikä ole, kun asciita ne Sepan XML:t kuuluu olla. Ulkomaille siirtyvät Sepat enkoodataan omassa pankissasi ennen jatkosiirtoa, jolloin ääkköset korvataan "¨??" tyyppsillä notaatioilla joita HTML:ssäkin käytetään.


      • Kalle vaan
        HighwayPatrol kirjoitti:

        Nyt tulostan ohjelmasta suoraan LMP-muotoisen tekstitiedoston, jonka lähetän pankkiohjelmalla eteenpäin. Tarkoitus olisi siis muuttaa lähtevä aineisto Sepa-muotoiseksi. Ei kai tagien tulostaminen koodista ole vaikeaa. Ongelmaksi voivat muodostua ääkköset esimerkiksi maksajan tai saajan nimessä.

        Osaan siis tulostaa ascii-muotoisen tekstitiedoston. Sitä en tiedä, tuleeko ääkkösistä ongelmaa. Oletan kuitenkin, että olisi parempi tulostaa UTF-8:na.

        "Osaan siis tulostaa ascii-muotoisen tekstitiedoston. Sitä en tiedä, tuleeko ääkkösistä
        ongelmaa. Oletan kuitenkin, että olisi parempi tulostaa UTF-8:na."

        Kannattaa puhua oikeilal termeillä, ei tuo mitään TULOSTAMISTA ole! Vaan ohjelmastasi käsin TALLETAT joksikin tiedostoksi, jotakin ohjelmasi dataa.

        Sinänsä LMP tiedostot ja SEPA tiedostot ovat ihan täsmälleen samanlaisella merkkituuballa tehty molemmat. Tässä kohdin nyt ei ole yhtään mitään uutta keksittävänä.

        Senkuin talletaa Delphistä Ascii-tiedostoksi ihan samoilla menetelmillä kuin on tehnyt on tehnyt Lmp-tiedostojakin. Notepadissa niitä tuotoksiaan voi sitten katsella.

        Uudemmat Notepadit tosin saattavat fuskata, ne yrittävät ymmärtää liikaa ja saattavat tehdä ruudulla näytettäville ääkköstyypin specialmerkeille jotakin mielestään tarpeellisia muunnoksia. Mutta jos testimielessä kertaalleen avaat tuotoksesi vaikka vanhassa MS-DOS:in EDIT-editorissa, tai vaikka Delphin omassa IDE:ssäkin, tms., niin ne ovat siitä hyviä että ne eivät tulkitse mitään, vaan näyttävät kaiken lahjomattomana ulos.


      • Delphikoodari..
        HighwayPatrol kirjoitti:

        Nyt tulostan ohjelmasta suoraan LMP-muotoisen tekstitiedoston, jonka lähetän pankkiohjelmalla eteenpäin. Tarkoitus olisi siis muuttaa lähtevä aineisto Sepa-muotoiseksi. Ei kai tagien tulostaminen koodista ole vaikeaa. Ongelmaksi voivat muodostua ääkköset esimerkiksi maksajan tai saajan nimessä.

        Osaan siis tulostaa ascii-muotoisen tekstitiedoston. Sitä en tiedä, tuleeko ääkkösistä ongelmaa. Oletan kuitenkin, että olisi parempi tulostaa UTF-8:na.

        Unohtakaa kaikki vanhat paskat, ASCII-merkistöt. UTF-8 on yhteensopiva ASCII:n kanssa ja tästä ylimenevä osuus on sitten Unicodea. UTF-8 on täysin riittävä kaikille merkeille.


      • delphiguru

        VÄÄRIN tehty !!!

        tuo 3-tavuinen os UTF-8 -enkoodattu BOM (Byte Order Mark).

        MUTTA:

        WideString käyttää UTF16LE -enkoodattua Unicodea.

        Siksipä, jos kirjoitat itse merkkijonon näin:

        const
        Utf8ByteOrderMark=#$EF#$BB#$BF;
        procedure WriteWideString(FilePath:string;x:WideString);
        var
        f:TFileStream;
        begin
        f:=TFileStream.Create(FilePath,fmCreate);
        try
        f.Write(Utf8ByteOrderMark,3);
        f.Write(x[1],Length(x)*2);
        finally
        f.Free;
        end;
        end;

        niin luonnollisesti silloin tuon BOM -merkin pitää olla enkoodattu UTF16LE -formaatissa, EIKÄ utf-8 formaatissa !

        Jos sellaisenaan käytät ylläolevaa koodia, niin huomaat että jos avaat tiedoston Windowsin NOTEPADilla (suom: muistio), silloin näkyy pelkkää roskaa.

        Syy: Alussa olevan BOM:in formaatti ei vastaa itse tietosisällön formaattia.

        Tee vaikkapa NOTEPADilla tiedosto, jossa on vain 1 merkki: "A". (ilman lainausmerkkejä).

        Tallenna se nimellä "koe1.txt" muodossa "Unicode" (Microsoftin kielenkäytössä
        Unicode = UTF-16LE).

        Sitten avaa tekstitiedosto "koe1.txt" debug.exe:llä näin:

        debug koe1.exe

        anna komento r (näyttää rekisterit)

        anna komento d (näyttää tiedoston 256 ensimmäistä tavua, tai koko tiedoston ja perässä satunnaista dataa 256 tavuun asti, jos tiedosto on alle 256 tavua).

        katso heksadesimaalidatasta 2 ensimmäistä tavua (koska UTF-16LE -muodossa BOM -merkki vie 2 tavua, kuten kaikki muutkin BMP:hen kuuluvat merkit).

        nuo 2 ensimmäistä tavua ovat BOM -merkki UTF-16 -esitysmuodossa, ja Delphi -koodissa tulee korvata näillä ylläoleva virheellinen:

        const
        Utf8ByteOrderMark=#$EF#$BB#$BF;

        Tuo ylläoleva ilmeisesti OLISI oikein, jos data olisi UTF-8 -formaatissa, ks. UTF8String sekä AnsiToUTF8 ja UTF8ToAnsi -funktiot.

        Mutta WideStringin esitysmuoto on UTF-16LE, eikä UTF-8.

        BMP = Basic Multilingual Page = ensimmäiset noin 63000 merkkiä.

        Teoreettinen maksimi olisi 65536, mutta

        a) osa koodeista on erikoiskäytössä kuten esim. LOW and HIGH surrogates; näiden (käytetään AINA parina) avulla esitetään muut kuin BMP:hen kuuluvat merkit.

        b) osa koodeista on eri syistä pysyvästi varattu, eli niitä ei käytetä. Esim: BOM:n byteswapattu esitys on tällainen se on pysyvästi kielletty, jotta ei syntyisi sekaannusta oikean BOM:in kanssa.

        Eli jos lukiessasi UTF-16 -enkoodattua tiedostoa alussa on byteswapattu BOM, silloin endianness on väärin, ja sinun täytyy silloin lukea data 2 tavun yksiköissä (Delphissä WORD), ja byteswapata kukin WORD.

        esim: $FFFE -> $FEFF.


    • Delphikoodari..

      Löytyy täältä! Itse koodailen edelleen Delphi 2006:lla, joka ei ole "Unicode" tuettu, mutta täältä löytyy kirjastot millä handlaat Unicoden (UTF-8) esim.

      Olen koodannut sovellusta, jonka pitää käsitellä venäjänkielisiä kyriillisiä merkkejä. Käytä vain Delphissä WideString muuttujia merkkijonoille ja linkin työkalut hoitaa loput :)

      http://fundementals.sourceforge.net/unicode.html

      Jos tarvitset Unicode-komponentteja Delphiin, eli komponentit jotka tukee unicodea, asenna TNT-komponentit, pitäisi onnistua vaikka kiinalaiset merkit :)

      http://www.google.com/search?client=safari&rls=en&q=delphi tnt-control&ie=UTF-8&oe=UTF-8

    Ketjusta on poistettu 0 sääntöjenvastaista viestiä.

    Luetuimmat keskustelut

    1. Poliisitehtävä alkuviikosta Maisan kotona

      Iltasanomat: Helsingin poliisilaitos vahvistaa, että Vantaalla on ollut poliisitehtävä kyseisenä ajankohtana. Poliisin
      Kotimaiset julkkisjuorut
      88
      2079
    2. Tämä on sinulle vaikka kaikki lukee

      Vaikka kuinka olet viisas ja kaikin puolin velho, niin et tiedä tilanteestani. Senkin takia menetät mielenkiinnon. Eikä
      Tunteet
      11
      1692
    3. T-mies tässä

      Kerro nainen huolesi niin pohditaan yhdessä. 😎
      Ikävä
      102
      1162
    4. Lulu selvityttää Elokapinan lakkautusta

      Persukannattajien mielistely otti Lulu Ranteella aika tavalla runtua, kun hän aikoo selvityttää mahdollisuuksia Elokapin
      Maailman menoa
      350
      1136
    5. Ensitreffit Matti joutuu "ulkoruokintaan" - Väärinymmärrysten suossa Taina-vaimon kanssa: "Oli..."

      No nyt on kyllä väärinymmärrystä kerrakseen… Mitä luulet, pysyykö Taina ja Matti yhdessä vai onko tulevaisuudessa ero ed
      Ensitreffit alttarilla
      3
      1123
    6. Harmi, kun sillä nousi

      kaikki huomio päähän. Vaikutti aluksi niin mukavalta ja vaatimattomalta 😔
      Ikävä
      53
      851
    7. Täytyy sanoa

      Että olit kyllä mielenkiintoisin ja omaperäisin nainen mitä olen koskaan tavannut. Aivan kuin joku olisi tiputtanut sinu
      Ikävä
      21
      839
    8. Miten saisin

      Hurmattua sinut uudelleen,? Pissin omiin muroihini ensinmäisellä kerralla koska olin tyhmä ja liiaksi kiinni menneess
      Ikävä
      31
      787
    9. Persu Meri Valkama kadehtii Sanna Marinin menestystä

      Taas yksi persu tuli nolaamaan itsensä kadehtiessaan menestynyttä Suomen kansan supertähteä Sanna Marinia. https://demo
      Maailman menoa
      237
      737
    10. Raamatun tärkein lause

      Ja Mooses tuli alas vuorilta missä jumala oli, Mooseksen mukaan, ilmoittanut hänelle, että hän ja koko juutalainen väki,
      Hindulaisuus
      367
      719
    Aihe