Autor Téma: Číselný datový typ a binární zápis  (Přečteno 1112 krát)

Offline vangog

  • Hrdina
  • ****
  • Příspěvků: 262
  • Karma: 0
    • Verze Delphi: 7
Re:Číselný datový typ a binární zápis
« Odpověď #15 kdy: 06-07-2018, 23:35:35 »
Hmmm, jsme na platforme wintel a tam je widechar datovy typ reprezentujici jeden 16-bitovy unicode znak v kodovani UTF16. Tecka.

A abych ti doporucil, jak to kodovat, tak bych musel vedet, k cemu to ma slouzit. Protoze matlat neco v bufferu neni zcela jiste cil ale prostredek buhvi k cemu. Zatim to na me dela dojem, ze se dost nesikovne snazis udelat message pool...

Chci si ukládat slovíčka do souboru. Něco jako slovník. Přidávat slovíčka a moci je vylovit to je celé. Celý soubor by měl mít maximální velikost několik kilobajtů. Nevím přesně kolik to bude mít bytů, ale určitě ne více než 200KB.

Zatím jsem nenašel žádný větší typ než widechar, takže z toho co jsem se od tebe dozvěděl zatím to beru tak, že podle tebe D7 neumí ukládat cizokrajné ("exotické") texty do souboru. Takový závěr jsem si udělal z tvých postů.

Výběr z některých jazyků:
arabština hodnota znaků se pohybuje od 1569 do 1574.
jap. katakana od 12449 až 12539.
jap. hiragana 3041 až 3094.
(u katakany a hiragany beru jen slabiky) jinak tam jsou nějaké fonetické rozšíření až do 65439.

Takže tyto jazyky se do dvou bytů pravděpodobně vejdou. Takže pokud ty větší hodnoty neumí D7 zpracovat, tak bych tyto jazyky vynechal. To by ale chtělo nejprve zjistit, jakou hodnotu tyto znaky mají. To vlastně mohu udělat nahlédnutím do PSPadu, ale bylo by lepší mít na to algoritmus.

Edit:
Jazyky co přesahují dva byty:
- Gothic
- Old Turkic
Víc jsem nenašel. Nemyslím, že by to bylo tak horké.
« Poslední změna: 07-07-2018, 00:03:30 od vangog »

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2342
  • Karma: 126
    • Verze Delphi: D2007, XE3, DX10
Re:Číselný datový typ a binární zápis
« Odpověď #16 kdy: 07-07-2018, 01:10:42 »
Chci si ukládat slovíčka do souboru. Něco jako slovník. Přidávat slovíčka a moci je vylovit to je celé. Celý soubor by měl mít maximální velikost několik kilobajtů. Nevím přesně kolik to bude mít bytů, ale určitě ne více než 200KB.
Ztrata casu: vstup mas podle vseho v UTF8, ale zase nepises, v jakem kodovani to chces do souboru zapisovat :-(

Offline vangog

  • Hrdina
  • ****
  • Příspěvků: 262
  • Karma: 0
    • Verze Delphi: 7
Re:Číselný datový typ a binární zápis
« Odpověď #17 kdy: 07-07-2018, 01:46:02 »
Chci si ukládat slovíčka do souboru. Něco jako slovník. Přidávat slovíčka a moci je vylovit to je celé. Celý soubor by měl mít maximální velikost několik kilobajtů. Nevím přesně kolik to bude mít bytů, ale určitě ne více než 200KB.
Ztrata casu: vstup mas podle vseho v UTF8, ale zase nepises, v jakem kodovani to chces do souboru zapisovat :-(
Nejlépe v UTF-8

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2342
  • Karma: 126
    • Verze Delphi: D2007, XE3, DX10
Re:Číselný datový typ a binární zápis
« Odpověď #18 kdy: 07-07-2018, 07:12:48 »
Nejlépe v UTF-8
No a na co potrebujes WideChar a podobne zalezitosti?  :o

Proste UTF8 nactes do ANSIStringu - on D7 stejne nic vic nepodporuje. A jako posloupnost bytu ten UTF8 zase do souboru zapises.
A posloupnost bytu je stream, takze se nemusis patlat s buffery, zejmena kdyz ti chybi elementarni zaklady prace s datovymi typy.

Implementace zapisu slovniku s tabulkou offsetu pak muze vypadat treba takhle:
Kód: Delphi [Vybrat]
  1. program GenTextPool;
  2.  
  3. {$APPTYPE CONSOLE}
  4.  
  5. uses
  6.   Classes, Windows, SysUtils;
  7.  
  8. const
  9.   SAMPLE_TEXTS_COUNT = 20;
  10. type
  11.   TCountType = dword;
  12.   TOffsetType = dword;
  13.   TTextType = ANSIString;
  14. var
  15.   fsOutput: TFileStream;
  16.   fileName: string;
  17.   msOffsets: TMemoryStream;
  18.   ofs: TOffsetType;
  19.   ofsTableEntries: TCountType;
  20.   text: TTextType;
  21.   i: integer;
  22.   genLng: integer;
  23.   genCh: char;
  24.   lng: integer;
  25. begin
  26.   try
  27.     msOffsets := TMemoryStream.Create;
  28.     try
  29.       fileName := 'C:\Temp\MessagePoolExample.Bin';
  30.       if FileExists(fileName) then
  31.         DeleteFile(fileName);
  32.       fsOutput := TFileStream.Create(fileName, fmCreate);
  33.       try
  34.         ofs := sizeof(ofs); // placeholder pro offset zacatku tabulky se zacatky offsetu textu
  35.         fsOutput.Write(ofs,sizeof(ofs));
  36.  
  37.         ofsTableEntries := 0;
  38.         for i:= 1 to SAMPLE_TEXTS_COUNT do
  39.           begin
  40.             genCh := char(ord('A')+random(26));
  41.             genLng := 1+random(64);
  42.             text := StringOfChar(genCh, genLng);
  43.             msOffsets.Write(ofs, sizeof(ofs));
  44.             lng := Length(text);
  45.             fsOutput.Write(text[1], lng);
  46.             inc(ofs,lng);
  47.             inc(ofsTableEntries);
  48.           end;
  49.  
  50.           fsOutput.Write(ofsTableEntries, sizeof(ofsTableEntries));  //Pred tabulkou je pocet polozek
  51.           fsOutput.Write(msOffsets.Memory^, msOffsets.Size);
  52.           fsOutput.Seek(0, soFromBeginning);
  53.           fsOutput.Write(ofs,sizeof(ofs));  //Aktualizace skutecneho offsetu zacatku tabulky
  54.  
  55.         finally
  56.           fsOutput.Free;
  57.         end;
  58.     finally
  59.       msOffsets.Free;
  60.     end;
  61.  
  62.   except
  63.     on E:Exception do
  64.       Writeln(E.Classname, ': ', E.Message);
  65.   end;
  66. end.
  67.  
  68.  

Offline vangog

  • Hrdina
  • ****
  • Příspěvků: 262
  • Karma: 0
    • Verze Delphi: 7
Re:Číselný datový typ a binární zápis
« Odpověď #19 kdy: 07-07-2018, 10:36:47 »
Díky za kód, ale chtěl bych si vyzkoušet vložit si tam nějaký text do toho bufferu ať si mohu prohlédnout jak se zapíše. Zatím jsem nepochopil jak to funguje. Vidím že hned na začátku mažeš soubor, to je soubor s tím slovníkem? Jestli jo tak proč ho přepisuješ? V něm mají být data, ne?

Už chápu že ty data náhodně generuješ v té smyčce.

Tak zatím jsem si tvůj kód upravil a zjednodušil, aby mě nemátla ta smyčka.

Kód: Delphi [Vybrat]
  1. unit writeDict;
  2.  
  3. interface
  4.  
  5. uses
  6.   Classes, Windows, SysUtils;
  7.  
  8. type
  9.   TCountType = dword;
  10.   TOffsetType = dword;
  11.   TTextType = ANSIString;
  12.  
  13. const
  14.   testText = 'Žluouèký kùò úpìl nebeské ódy.';
  15. const
  16.   testItemsCount = 1;
  17.  
  18. type writeMyDict = class
  19.   private
  20.     fsOutput: TFileStream;
  21.     fileName: string;
  22.     msOffsets: TMemoryStream;
  23.     ofs: TOffsetType;
  24.     ofsTableEntries: TCountType;
  25.     text: TTextType;
  26.  
  27.     genLng: Longint;
  28.     genCh: char;
  29.  
  30.     lng: integer;
  31.     public
  32.     procedure writeDic();
  33.   end;
  34.  
  35. implementation
  36.  
  37. procedure writeMyDict.writeDic();
  38. var i: integer;
  39. begin
  40.     try
  41.       msOffsets := TMemoryStream.Create;
  42.       try
  43.         fileName := 'A:\MessagePoolExample.Bin';
  44.         if FileExists(fileName) then
  45.           DeleteFile(fileName);
  46.         fsOutput := TFileStream.Create(fileName, fmCreate);
  47.         try
  48.           ofs := sizeof(ofs); // placeholder pro offset zacatku tabulky se zacatky offsetu textu
  49.           fsOutput.Write(ofs,sizeof(ofs));
  50.  
  51.           ofsTableEntries := testItemsCount;
  52.  
  53.           genCh := char(ord('A')+random(26));
  54.           genLng := 1+random(64);
  55.           text := testText;
  56.           msOffsets.Write(ofs, sizeof(ofs));
  57.           lng := Length(text);
  58.           fsOutput.Write(text[1], lng);
  59.           inc(ofs,lng);
  60.  
  61.           fsOutput.Write(ofsTableEntries, sizeof(ofsTableEntries));  //Pred tabulkou je pocet polozek
  62.           fsOutput.Write(msOffsets.Memory^, msOffsets.Size);
  63.           fsOutput.Seek(0, soFromBeginning);
  64.           fsOutput.Write(ofs,sizeof(ofs));  //Aktualizace skutecneho offsetu zacatku tabulky
  65.  
  66.           finally
  67.             fsOutput.Free;
  68.           end;
  69.       finally
  70.         msOffsets.Free;
  71.       end;
  72.    
  73.     except
  74.       on E:Exception do
  75.         Writeln(E.Classname, ': ', E.Message);
  76.     end;
  77. end;
  78.  
  79. end.
  80.  
« Poslední změna: 07-07-2018, 11:05:00 od vangog »

Offline vangog

  • Hrdina
  • ****
  • Příspěvků: 262
  • Karma: 0
    • Verze Delphi: 7
Re:Číselný datový typ a binární zápis
« Odpověď #20 kdy: 07-07-2018, 11:11:24 »
A mohl bys prosím tě ten kód ještě rozšířit abych si mohl prohlédnout v běžném txt souboru jak vypadají jednotlivé položky v UTF-8?
Mít tam funkci, kterou bych zavolal, která ty položky načte a pak zapíše do txt. Protože v Delphi se to prohlížet nedá.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2342
  • Karma: 126
    • Verze Delphi: D2007, XE3, DX10
Re:Číselný datový typ a binární zápis
« Odpověď #21 kdy: 07-07-2018, 11:22:25 »
Excellent
Rated 1 time
A mohl bys prosím tě ten kód ještě rozšířit abych si mohl prohlédnout v běžném txt souboru jak vypadají jednotlivé položky v UTF-8?
Mít tam funkci, kterou bych zavolal, která ty položky načte a pak zapíše do txt. Protože v Delphi se to prohlížet nedá.

Ucit programovat te nehodlam a psat za tebe tvoje ukoly taky ne.

Offline vangog

  • Hrdina
  • ****
  • Příspěvků: 262
  • Karma: 0
    • Verze Delphi: 7
Re:Číselný datový typ a binární zápis
« Odpověď #22 kdy: 07-07-2018, 11:53:06 »
Ucit programovat te nehodlam a psat za tebe tvoje ukoly taky ne.

Ale děláš to.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 3697
  • Karma: 35
    • Verze Delphi: XE7 professional
Re:Číselný datový typ a binární zápis
« Odpověď #23 kdy: 07-07-2018, 12:11:15 »
Excellent
Rated 1 time
Citace
Ale děláš to.
Buď rád a váž si to! Venovali sa Ti tu viac než dosť. Čudujem sa, že ešte nezapichli vidly do hnoja :o
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline vangog

  • Hrdina
  • ****
  • Příspěvků: 262
  • Karma: 0
    • Verze Delphi: 7
Re:Číselný datový typ a binární zápis
« Odpověď #24 kdy: 07-07-2018, 12:58:11 »
Citace
Ale děláš to.
Buď rád a váž si to! Venovali sa Ti tu viac než dosť. Čudujem sa, že ešte nezapichli vidly do hnoja :o

No však. Ale myslím že jsem to už pochopil tak ten read snad dám.

Offline vangog

  • Hrdina
  • ****
  • Příspěvků: 262
  • Karma: 0
    • Verze Delphi: 7
Re:Číselný datový typ a binární zápis
« Odpověď #25 kdy: 07-07-2018, 18:48:24 »
Zkouším vlastní metodu:
Kód: Delphi [Vybrat]
  1. procedure Dictionary.dicRewrite();
  2. var i: integer;
  3.     text: TTextType;
  4. begin
  5.     itemsCount := 0;
  6.     header := StringOfChar(char(1), 11*offsetSize);
  7.     header[3] := chr(length(header)+offsetSize); // fist data would start here
  8.     text := StringOfChar(char(0), 1);
  9.     // 12 - pozice je volné místo pro zápis dat
  10.       try
  11.         fileName := 'A:\MessagePoolExample.Bin';
  12.         if FileExists(fileName) then
  13.           DeleteFile(fileName);
  14.         fsOutput := TFileStream.Create(fileName, fmCreate);
  15.         try
  16.           fsOutput.Write(header,Length(header));
  17.         finally
  18.         end;
  19.       finally
  20.         fsOutput.Free;
  21.       end;
  22. end;
  23.  

Má to jen vytvořit nový soubor s nulama na začátku a na indexu 3 až 4 má být dvoubajtová informace o začátku datové části.

Vytvoří mi to soubor, který vůbec neodpovídá tomu co chci zapsat

Zkopíroval jsem hexadecimální kód ze souboru prohlíženého v PSPadu:
C026A300160000000100000006000000264C656B63650000B2000000BC4D45005C1EA300306CA30000000000

Čím to je a jak to opravit? Už když jsem tam chtěl zapsat jen nuly tak to tam psalo nesmysly. Vlastně jsem se jen snažil zopakovat co napsal pf1957 jen jsem upravil hodnoty pro zápis.
« Poslední změna: 07-07-2018, 18:50:54 od vangog »

Offline vangog

  • Hrdina
  • ****
  • Příspěvků: 262
  • Karma: 0
    • Verze Delphi: 7
Re:Číselný datový typ a binární zápis
« Odpověď #26 kdy: 08-07-2018, 10:42:54 »
opraveno
Kód: Delphi [Vybrat]
  1. header[1]
nebo
Kód: Delphi [Vybrat]
  1. PAnsiChar(header)^

Nebo s typem array of byte:
Kód: Delphi [Vybrat]
  1. PByte(header)^
« Poslední změna: 08-07-2018, 10:44:31 od vangog »

Offline vangog

  • Hrdina
  • ****
  • Příspěvků: 262
  • Karma: 0
    • Verze Delphi: 7
Re:Číselný datový typ a binární zápis
« Odpověď #27 kdy: 10-07-2018, 00:30:58 »
Když data mám TBytes a str je string, mohu to normálně kopírovat?
Teď se mi stalo, že pro provedení move se mi přepsal header.
Kód: Delphi [Vybrat]
  1. setlength(data, length(str));
  2. move(str, data, length(str));
  3.  

Str je string který obsahuje data, která chci zapsat.

Kód: Delphi [Vybrat]
  1. fsOutput.Write(data[0],Length(header));
  2.  

ovšem nevím proč se přepsal header (v prvním kodu na 3. řádku).

A proč když mám ve zdrojovém souboru napsané:

ahoj
jak
se
mate
dnes
je
utery
0:24

po načtení SourceList.LoadFromFile('a:\source_simple.txt');
první slovíčko má hodnotu 'ahoj'
V souboru je normální 'a', ASCII 97
« Poslední změna: 10-07-2018, 00:37:41 od vangog »

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 1407
  • Karma: 58
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:Číselný datový typ a binární zápis
« Odpověď #28 kdy: 10-07-2018, 07:23:08 »
po načtení SourceList.LoadFromFile('a:\source_simple.txt');
první slovíčko má hodnotu 'ahoj'
V souboru je normální 'a', ASCII 97

To je BOM. Chapu spravne ze cely ukol je o nacteni souboru v UTF-8 enkodovani do Unicode kolekce retezcu s moznosti jejiho nasledneho ulozeni do souboru s enkodovanim UTF-8? Pokud ano, k cemu je cely ten vlastni binarni format s offsety a kdovi cim jeste? Je Ti jasne ze takovy vlastni format nebude platnym UTF-8 souborem?
« Poslední změna: 10-07-2018, 07:29:01 od Delfin »
I'm a soldier, so don't panic! I know the underground! I like WTFPL license! No more Google, go duck, go!

Offline vangog

  • Hrdina
  • ****
  • Příspěvků: 262
  • Karma: 0
    • Verze Delphi: 7
Re:Číselný datový typ a binární zápis
« Odpověď #29 kdy: 10-07-2018, 08:06:34 »
To je BOM. Chapu spravne ze cely ukol je o nacteni souboru v UTF-8 enkodovani do Unicode kolekce retezcu s moznosti jejiho nasledneho ulozeni do souboru s enkodovanim UTF-8? Pokud ano, k cemu je cely ten vlastni binarni format s offsety a kdovi cim jeste? Je Ti jasne ze takovy vlastni format nebude platnym UTF-8 souborem?

Myslel jsem že BOM se vynechá automaticky. Přece jsem už touto metodou načítal soubor ini... No a jak mám teda ten bom přeskočit, aby se to nezahrnulo do Toho seznamu? Musím to teda odladit ručně pomocí substr?

Tak jasně, že pracuji s binárním souborem a ne UTF-8.

Celý projekt je o vyexportování velkého množství textu z velkého souboru.

 

S rychlou odpovědí můžete používat BB kódy a emotikony jako v běžném okně pro odpověď, ale daleko rychleji.

Upozornění: do tohoto tématu bylo naposledy přispěno před 120 dny.
Zvažte prosím založení nového tématu.

Jméno: E-mail:
Ověření:
Kolik je šest plus čtyři (slovem):