Forum Delphi.cz

Delphi => Obecné => Téma založeno: vangog 16-09-2018, 19:03:45

Název: Nedaří se mi načíst data
Přispěvatel: vangog 16-09-2018, 19:03:45
Kód: Delphi [Vybrat]
  1. SubDirs, FileList, line, TargetFile: TStringList;
  2. m, n: integer;
  3. FileHandle : Integer;
  4. fSize: Integer;
  5.  
  6. begin
  7.  
  8.   SourceList := TStringList.create;
  9.   FileList := TStringList.create;
  10.   TargetFile := TStringList.create;
  11.   SubDirs := TStringList.create;
  12.  
  13.   createDirsList('b:\html', SubDirs);
  14.  
  15.   if not DirectoryExists('b:\output.html') then
  16.     mkdir('b:\output.html');
  17.   for m:=0 to SubDirs.count-1 do
  18.     begin
  19.     FileList.clear;
  20.     createFilesList('b:\html\' + SubDirs[m] , '.htm', FileList);
  21.     s := 'b:\output.html\' + SubDirs[m];
  22.     if not DirectoryExists(s) then
  23.       mkdir(s);
  24.   for i:=0 to FileList.count-1 do
  25.     begin
  26.       SourceList.clear;
  27.       TargetFile.clear;
  28.  
  29.       FileHandle := FileOpen('b:\html\' + SubDirs[m] + '\' + FileList[i], fmOpenRead);
  30.       fSize := FileSeek(FileHandle,0,soFromEnd);
  31.       FileSeek(FileHandle,0,soFromBeginning);
  32.       setLength(buffer, fSize);
  33.       FileRead(FileHandle, buffer , fSize );
  34.       setLength(buffer, ansipos('$', buffer ) );
  35.       fileclose(FileHandle);
  36.       FileHandle := FileOpen(s + '\' + FileList[i], fmOpenWrite);
  37.       FileWrite(FileHandle, buffer , fSize );
  38.       fileclose(FileHandle);
  39.  
  40.       TargetFile.SaveToFile('b:\output.html\' + SubDirs[m] + '\' + ChangeFileExt(FileList[i], '.html'));
  41.       TargetFile.clear;
  42.     end; // n loop files
  43.     end; // m loop directories
  44.  

Problematická část:

Kód: Delphi [Vybrat]
  1. setLength(buffer, fSize);
  2. FileRead(FileHandle, buffer , fSize );
  3. setLength(buffer, ansipos('$', buffer ) );
  4.  

buffer je typ string, ale když nedám setLength(buffer, fSize); tak se nic nenačte do bufferu. Když použiju seLenght tak přes kukátko vidí, že tam jsou načtené nějaké čísla, ale zdrojový soubor je html stránka, takže text. Takže se ptám co musím udělat aby to vidělo text? Já chci v souboru najít značku '$' respektive '$>' a odtud soubor zkrátit.

PS:
Jedná se o jednoúčelový kód, chci jen zkrátit soubory o marast, který je nakonci.
Název: Re:Nedaří se mi načíst data
Přispěvatel: JaroB 16-09-2018, 19:57:10
je-li buffer string, pak se načítá od indexu 1

FileRead(FileHandle, buffer[1] , fSize );
Název: Re:Nedaří se mi načíst data
Přispěvatel: vangog 16-09-2018, 20:02:07
Díky, na toto jsem už zase zapomněl. Teď už to jede.
Název: Re:Nedaří se mi načíst data
Přispěvatel: vangog 16-09-2018, 20:11:29
Ještě dotaz,

Kód: Delphi [Vybrat]
  1. s := 'b:\output.html\' + SubDirs[m] + '\' + ChangeFileExt(FileList[i], '.html');
  2. FileHandle := FileOpen(s, fmCreate ); // or fmOpenWrite
  3.  

Chci zapsat data, soubor neexisutje, ale FileHandle je -1 . Cesta ale je v pořádku,
kde je problém?
Název: Re:Nedaří se mi načíst data
Přispěvatel: Stanislav Hruška 16-09-2018, 21:30:37
V uvedenom texte chybu nevidím. Takže mi napadajú jedine prístupové práva.
Mňa však zaujalo čosi iné. Preto aj pišem. A to v ceste uvedený disk B. V OS W sú písmená A, B vyhradené pre flopy disky a OS ich HD odmieta prideliť. Iné OS nepoznám, ale uvedný text poukazuje na W. Takže ma technicky zaujíma ako si sa k tomu B dopracoval.
Název: Re:Nedaří se mi načíst data
Přispěvatel: vandrovnik 16-09-2018, 22:02:48
Kód: Delphi [Vybrat]
  1. s := 'b:\output.html\' + SubDirs[m] + '\' + ChangeFileExt(FileList[i], '.html');
  2. FileHandle := FileOpen(s, fmCreate ); // or fmOpenWrite

Chci zapsat data, soubor neexisutje, ale FileHandle je -1 . Cesta ale je v pořádku,
kde je problém?

Pokud celá cesta doopravdy existuje (fakt má ta složka ve svém názvu .html?), tak bych zkusil fmCreate or fmShareDenyWrite. Ale spíš bych tipoval na zradu v té cestě.
Název: Re:Nedaří se mi načíst data
Přispěvatel: vangog 16-09-2018, 22:22:43
Cesta s je 'b:\output.html\alfa\aaro_n_2.html'
ten soubor není vytvořen, má se vytvořit při zápisu dat. Jinak cesta b:\output.html\alfa\ je ok.

a: a b: jsou v mém PC ramdisky; takže vlastně "virtuální" disky. Vytváření souborů jsem už dělal, ale pomocí TStringList, což není tento případ. Používám Ramdisky často, abych množství provizorních dat zbytečně neukládal na pevný disk.

PS:
Ani toto nepomohlo:

Kód: Delphi [Vybrat]
  1. s := 'b:\test.html';
  2. FileHandle := FileOpen(s, fmCreate  or fmShareDenyWrite);
  3. [code=delphi]

Ani c:\...
Název: Re:Nedaří se mi načíst data
Přispěvatel: vandrovnik 16-09-2018, 22:25:42
Vytváření souborů jsem už dělal, ale pomocí TStringList, což není tento případ.

Já bych teda stejně doporučoval použít tFileStream, třeba se tím záhada vyřeší...

Název: Re:Nedaří se mi načíst data
Přispěvatel: JaroB 17-09-2018, 08:33:35
Proč si to tak komplikovat?
Existuje něco jako
Kód: Delphi [Vybrat]
  1.   if DirectoryExists(ExtractFilePath(s)) then...

k ověření že cesta existuje.

  Nebo rovnou
Kód: Delphi [Vybrat]
  1.   if FileExists(s) then

jinak lze do stringlistů lehce načíst celý soubor a pak s tím pracovat nejen po řádkách ale i jako s textem v řetězci

Kód: Delphi [Vybrat]
  1. var strlst: TStringList;
  2. ...
  3.   strlst.LoadFromFile(s); //nacti
  4.   str := strlst.Text; //do retezce
  5.   ...
  6.   strlst.Text := str; //zpatky
  7.   strlst.SaveToFile(s); //uloz
Název: Re:Nedaří se mi načíst data
Přispěvatel: vangog 17-09-2018, 09:56:17
jinak lze do stringlistů lehce načíst celý soubor a pak s tím pracovat nejen po řádkách ale i jako s textem v řetězci

OK, dík za tipy.
Název: Re:Nedaří se mi načíst data
Přispěvatel: vangog 17-09-2018, 11:34:36
Přiznám se ale že používat k tomu TStringList mi přijde neefektivní vzhledem k velkému množství souborů kterých jsou tisíce.
Název: Re:Nedaří se mi načíst data
Přispěvatel: JaroB 17-09-2018, 11:55:51
Jak vypadají ony soubory (obsah, struktura, velikost)?
Název: Re:Nedaří se mi načíst data
Přispěvatel: vangog 17-09-2018, 12:38:05
Jak vypadají ony soubory (obsah, struktura, velikost)?

Html obsahující angličtinu, řečtinu nebo hebrejštinu. Občas jsou tam i znaky s výslovností. Velikost desítky kilobyte. Struktura html.
Název: Re:Nedaří se mi načíst data
Přispěvatel: JaroB 17-09-2018, 12:47:01
Pokud jsou v utf8 je možné je načíst do stringlistu bez problémů (D2009+).
Údaje, které obsahují, se čtou a ukládají do DB nebo se s nimi dál nějak pracuje (mění se, nebo se jen čtou ve stejném formátu)?
Název: Re:Nedaří se mi načíst data
Přispěvatel: vangog 17-09-2018, 18:56:39
Pokud jsou v utf8 je možné je načíst do stringlistu bez problémů (D2009+).
Údaje, které obsahují, se čtou a ukládají do DB nebo se s nimi dál nějak pracuje (mění se, nebo se jen čtou ve stejném formátu)?

Jak jsem psal, chci jen zkrátit data, nic víc. Ale přijde mi zbytečné to parsovat což stringlist dělá.
Název: Re:Nedaří se mi načíst data
Přispěvatel: vangog 17-09-2018, 19:41:34
Ještě jsem to nevzdal. A už jsem to rozjel.

Kód: Delphi [Vybrat]
  1. FileHandle := FileCreate(s);
  2. if (FileHandle < 1) then
  3.                              showmessage('Ah' + inttostr(FileHandle) );
  4. FileWrite(FileHandle, buffer[1] , length(buffer) );
  5. fileclose(FileHandle);
  6.  

O té funkci FileCreate jsem se dozvěděl až teď.
Název: Re:Nedaří se mi načíst data
Přispěvatel: pepak 18-09-2018, 06:16:13
Myslím, že tohle dobře demonstruje, co děláš špatně:

1) Předčasná optimalizace. Na prvním místě by ses měl snažit napsat program tak, aby fungoval a aby se dal udržovat, a teprve když to máš splněno, má smysl řešit optimalizaci. A to na základě konkrétních dat, tedy měření, která část programu je pomalá, ne podle odhadu od stolu.

2) Nesrozumitelné zápisy. Až ten program dokončíš, půl roku bude chodit k tvé plné spokojenosti a potom na tebe vyhodí hlášku "Ah5423852", budeš schopen říct, co tím myslí?

3) Používání nevhodných konstrukcí. FileCreate a spol. rozhodně mají svůj smysl, ale jsou to nízkoúrovňové funkce, fakticky obal sjednodcující volání v různých operačních systémech. Jako takové mají velmi omezenou použitelnost pro programátora - slouží hlavně tvůrcům základních knihoven. Programátor by měl používat buď vysokoúrovňové abstrakce (TFileStream), nebo přímo volání OS (CreateFile), pokud pro ně má rozumné uplatnění (např. nastavení režimů, které wrapper neumí, třeba vypnutí bufferování pod Windows). Tvoje chyba není v tom, že nevíš, že to jsou nevhodné konstrukce, to je u začátečníka přirozené, ale v tom, že nejsi ochoten přijmout doporučení zkušenějších.

4) Neřešení mezních stavů. Jaké hodnoty ti může vrátit funkce FileCreate? Za jakých okolností k tomu dojde? Pokud už ta situace nastane, jak přesně se tvůj program zachová? V kódech na předchozí stránce například: Co program udělá, pokued požadovaný adresář neexistuje? Atd.
Název: Re:Nedaří se mi načíst data
Přispěvatel: vangog 18-09-2018, 12:47:00
Myslím, že tohle dobře demonstruje, co děláš špatně:

Těmihle věcmi se nezabývám, protože jde o jednorázovou záležitost. Použiju to jednou a nikdy více. Podobně jako zrovna teď potřebuju ve všech souborech nahradit <START> za new_line + carriage_return (vložení nového řádku místo <START>). Použiju to jednou a nikdy více. Normálně na záměnu řetězců používám PSPad, ale tuhle operaci neumí (aplikovat na všechny hledané soubory). Tak si na to musím napsat program.

PS: Souborů je asi 65000 a jsou uložené na RAM disku, takže v PSPAdu to trvá několik minut než se vše projde a zedituje.
Název: Re:Nedaří se mi načíst data
Přispěvatel: JaroB 18-09-2018, 13:01:12
Důležité je mít odladěn algoritmus pro jeden soubor, pak se dá snadno zřetězit i pro tisíce. Tak bych to asi dělal já.
A jestli je to jednorázová záležitost, tak potom už na nějaké té minutě navíc snad ani nezáleží.
Název: Re:Nedaří se mi načíst data
Přispěvatel: Delfin instaluje 18-09-2018, 14:12:12
Podobně jako zrovna teď potřebuju ve všech souborech nahradit <START> za new_line + carriage_return (vložení nového řádku místo <START>). Použiju to jednou a nikdy více. Normálně na záměnu řetězců používám PSPad, ale tuhle operaci neumí (aplikovat na všechny hledané soubory). Tak si na to musím napsat program.

Napr. https://github.com/zzzprojects/findandreplace (https://github.com/zzzprojects/findandreplace)?
Název: Re:Nedaří se mi načíst data
Přispěvatel: pepak 18-09-2018, 14:36:31
Myslím, že tohle dobře demonstruje, co děláš špatně:

Těmihle věcmi se nezabývám, protože jde o jednorázovou záležitost.
Pak si na to vzpomeň. Ale budiž, je to tvůj boj.

Citace
Podobně jako zrovna teď potřebuju ve všech souborech nahradit <START> za new_line + carriage_return (vložení nového řádku místo <START>). Použiju to jednou a nikdy více. Normálně na záměnu řetězců používám PSPad, ale tuhle operaci neumí (aplikovat na všechny hledané soubory). Tak si na to musím napsat program.
Nebo najít jiný program, který to umí. Kdybys například uměl regulární výrazy, tak to zvládneš udělat mnoha různými programy a nebudeš kvůli tomu muset nic programovat.
Taky by sis mohl nastudovat regulární výrazy a pak to udělat jedním z mnoha programů, které to dokážou.
Název: Re:Nedaří se mi načíst data
Přispěvatel: Delfin instaluje 18-09-2018, 14:46:27
Nebo najít jiný program, který to umí. Kdybys například uměl regulární výrazy, tak to zvládneš udělat mnoha různými programy a nebudeš kvůli tomu muset nic programovat.
Taky by sis mohl nastudovat regulární výrazy a pak to udělat jedním z mnoha programů, které to dokážou.

Tak urcite. Nicmene otazkou je, zda ma smysl se kvuli jednorazove uloze ucit regularni vyrazy. Osobne pouzivam grep, ale ten fnr vypada jako pomerne snadna "klikacka" a pro dany ucel by snad mohl stacit (bohuzel nevim zda podporuje zadani CRLF).

S tim ze OP obcas stavi raketoplan uz jsem se smiril :)
Název: Re:Nedaří se mi načíst data
Přispěvatel: vangog 18-09-2018, 14:50:09
[quote author=Delfin instaluje link=topic=16324.msg101538#msg101538
Tak urcite. Nicmene otazkou je, zda ma smysl se kvuli jednorazove uloze ucit regularni vyrazy. Osobne pouzivam grep, ale ten fnr vypada jako pomerne snadna "klikacka" a pro dany ucel by snad mohl stacit (bohuzel nevim zda podporuje zadani CRLF).

S tim ze OP obcas stavi raketoplan uz jsem se smiril :)
[/quote]

Regulární výrazy umím. Já používám toto
https://www.yunqa.de/delphi/products/regex/index
ale na replace jsem to ještě nepoužíval. Tak teď musím zahledat v nápovědě
Název: Re:Nedaří se mi načíst data
Přispěvatel: pepak 18-09-2018, 19:50:04
Tak urcite. Nicmene otazkou je, zda ma smysl se kvuli jednorazove uloze ucit regularni vyrazy.
Ano, má. Regexpy jsou univerzálně užitečné, určitě to nebude "jednorázová úloha".
Název: Re:Nedaří se mi načíst data
Přispěvatel: Delfin instaluje 18-09-2018, 20:59:03
Tak urcite. Nicmene otazkou je, zda ma smysl se kvuli jednorazove uloze ucit regularni vyrazy.
Ano, má. Regexpy jsou univerzálně užitečné, určitě to nebude "jednorázová úloha".

Hmno. Kdybych si potreboval hanhle osetrit trebas poranenou ruku, nebudu se ucit medicinu. Pokud jde o jednorazovou akci, netvoril bych kvuli tomu aplikaci ani se neucil regex. Pouzil bych hotova reseni. Ale co bych tady rikal...
Název: Re:Nedaří se mi načíst data
Přispěvatel: Delfin instaluje 18-09-2018, 21:47:15
Tak urcite. Nicmene otazkou je, zda ma smysl se kvuli jednorazove uloze ucit regularni vyrazy.
Ano, má. Regexpy jsou univerzálně užitečné, určitě to nebude "jednorázová úloha".
[/quote]

Mnohem vetsi smysl v dnesni dobe ma se naucit nejaky moderni jazyk, jako napr. C#. Regularni vyrazy, OK, ale netusim proc bych mel radit nekomu kdo chce udelat jednorazovou akci. Dobra, mnohokrat, stejnou (tezko z dotazu rict, mozna vis vic), ale proc se kvuli tomu kousat spoustou materialu kdyz by se dal napsat i regex vyraz pro find a replace a ten pouzit nekoikrat v navrhovanych aplikacich?

A ted do me :)
Název: Re:Nedaří se mi načíst data
Přispěvatel: vangog 18-09-2018, 22:27:28
Delfíne, já právě regulární výrazy používám už řadu let, občas se hodí i složitější věci.

Dejmetomu, že v jednotlivých jazycích jsou menší odlišnosti v aplikaci, ale to je popsáno v nápovědě. V tomto případě se mi vyplatí naučit se pracovat s knihovnou DIRegEx, protože ji plánuji používat i v budoucnu.

Tedy kód který si osvojím dnes, zase využiji příště. Regulární výrazy nejsou jednorázovou záležitostí, to stačí upravit v příštím použití.

PS:
Mám k tomu sice manuál, ale nejsem moudrý z toho, jak vygenerovat chybovou hlášku pomocí procedury

DIRegEx.TDIRegExBase.Error

proc class procedure Error(
  const ResStringRec: PResStringRec;
  const Args: array of const);
 
Description:
Raises an EDIRegExError exception with a message string that is loaded from the application’s resources and then formatted.

Nějaká pomoc?

PS 2:
class DIRegEx.EDIRegExError
Syntax
Syntax: type EDIRegExError = class(Exception)
Hierarchy: EDIRegExError > Exception
Description:
The exception type raised by TDIRegEx and TDIRegEx16 in case of errors.

PS 3:
field DIRegEx.TDIRegExBase.FErrorMessage
Syntax
field FErrorMessage: PAnsiChar;
Description:
Holds a pointer to the PCRE error string.
 
Název: Re:Nedaří se mi načíst data
Přispěvatel: pepak 18-09-2018, 22:34:05
ale proc se kvuli tomu kousat spoustou materialu kdyz by se dal napsat i regex vyraz pro find a replace a ten pouzit nekoikrat v navrhovanych aplikacich?
Protože regexpy využije skoro pořád, a proto se hodí je umět. Kromě toho "dal napsat regex výraz" je sice hezká teorie, ale v praxi je potřeba, aby to bylo napsané pro konkrétní nástroj, ve kterém se to bude dělat. Aneb, pomůže vangogovi nějak zásadně, když mu napíšu regulární výraz pro nástroj, který nemá, nezná a nejspíš ani znát nechce?

Ale pro mě za mě...

1) FAR Manager + plugin RESearch
2) Najet do adresare, kde chci provest zmeny
3) F11
4) Regular Expression Search
5) Replace
6) File mask = *.*
7) Search for = <start>
8) Replace with = \n
9) Regular expression
10) Search: From the current folder
11) Všechno ostatní odškrtnout
12) OK
13) Hotovo. Celkový čas kolik, minuta?
Název: Re:Nedaří se mi načíst data
Přispěvatel: pepak 18-09-2018, 22:37:00
Dejmetomu, že v jednotlivých jazycích jsou menší odlišnosti v aplikaci, ale to je popsáno v nápovědě. V tomto případě se mi vyplatí naučit se pracovat s knihovnou DIRegEx, protože ji plánuji používat i v budoucnu.
Osobně preferuju TPerlRegEx, která je zdarma (a tuším od XE2 přímou součástí Delphi), ale podle popisu se to zdá být velice podobné.

Citace
Tedy kód který si osvojím dnes, zase využiji příště. Regulární výrazy nejsou jednorázovou záležitostí, to stačí upravit v příštím použití.
Přesně tak. Upřímně řečeno mě překvapuje, že to Delfín neví.

Citace
PS 2:
class DIRegEx.EDIRegExError
Syntax
Syntax: type EDIRegExError = class(Exception)
Hierarchy: EDIRegExError > Exception
Description:
The exception type raised by TDIRegEx and TDIRegEx16 in case of errors.
Raise DIRegEx.EDIRegExError.Create('Něco se mi rozbilo');
Název: Re:Nedaří se mi načíst data
Přispěvatel: Delfin instaluje 18-09-2018, 23:01:25
Podobně jako zrovna teď potřebuju ve všech souborech nahradit <START> za new_line + carriage_return (vložení nového řádku místo <START>). Použiju to jednou a nikdy více.

Pro tohle, je podle Tebe pepaku treba psat aplikaci? Nebo se ucit regex? OMG ::) ;D
Název: Re:Nedaří se mi načíst data
Přispěvatel: Delfin instaluje 18-09-2018, 23:28:45
Ale nevadi, pro reseni dalsiho trivialniho problemu staci odcestovat vesmirem za nalezenim vyssi inteligence s balickem prazenych buraku ;D ;D Sorry, ja byl vzdycky sarkastik. Ta omluva samozrejme neni Tobe, pepaku :)
Název: Re:Nedaří se mi načíst data
Přispěvatel: pepak 19-09-2018, 06:10:32
Ale nevadi, pro reseni dalsiho trivialniho problemu staci odcestovat vesmirem za nalezenim vyssi inteligence s balickem prazenych buraku ;D ;D Sorry, ja byl vzdycky sarkastik. Ta omluva samozrejme neni Tobe, pepaku :)
Pouze dvě pozorování, vem si z nich, co považuješ za vhodné.

1) Možná by bylo vhodnější odpovídat až poté, co si zadané téma přečteš. Sice nebudeš mít tolik příspěvků, ale zase budou k věci.

2) Nějak postrádám to tvoje řešení, které nevyžaduje ani programování ani regexpy. Nezapomeň, mělo by být dramaticky jednodušší a rychlejší než to moje regexpové ve FARu, které jsem psal minutu. Jinak se trochu ztratí ta údernost srovnání s cestou vesmírem.
Název: Re:Nedaří se mi načíst data
Přispěvatel: vangog 19-09-2018, 09:33:43
Podobně jako zrovna teď potřebuju ve všech souborech nahradit <START> za new_line + carriage_return (vložení nového řádku místo <START>). Použiju to jednou a nikdy více.

Pro tohle, je podle Tebe pepaku treba psat aplikaci? Nebo se ucit regex? OMG ::) ;D

Pro toto konkrétně regex není třeba, ale já si zvolil přístup s regex, protože s tím beztak v budoucnosti budu pracovat. Psát aplikaci - jinou aplikaci nemám a neznám. Je roztzhodně jednodušší si ji napsat, což je rychlejší než studovat dokumenty jiné aplikace, kterou bych si dle doporučení měl stáhnout.