Jump to content

FileStream


Kline777

Recommended Posts

Boas,

Pergunta estúpida... Ao gravar um TFileStream dá para gravar em formato de ficheiro de texto ou fica sempre em formato binary?

Preciso de gravar umas boas centenas de milhares de linhas num ficheiro que tem de ser lido por uma máquina externa que só lê texto simples. Estou a usar o Assign,Reset, Writeln, mas andava a ver se conseguia arranjar alternativas para tentar optimizar o tempo de escrita... não é catastrófico mas ficava sempre bem mais rápido.

Tentei usar o FileStream e de facto a gravaçao é mais rápida, mas o ficheiro fica sempre em binary e a máquina n o consegue ler.

Obrigado.

Link to comment
Share on other sites

Não sei se percebi bem o que queres, mas podes converter uma stream em texto.

Crias uma TStringList

Depois de a inicializares, usas o método LoadFromStream para carregares o que tens em memoria na FileStream

Depois usas o método SaveToFile para gravar o ficheiro txt

Vê no entanto se só a TStringList (sem a FileStream) não te resolvem o problema!

É um método muito mais eficaz e rapido para usar ficheiros de texto que o writeln e companhia...

"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Link to comment
Share on other sites

Basicamente o objectivo é ler as linhas de n ficheiros de texto para uma lista de records, tratar a informaçao e gravar num ficheiro final.

Esse ficheiro final pode ficar com Milhões de linhas... eu queria acelerar a gravação, mas usar a TStringList traz-me o problema de ocupar demasiado espaço na memória até gravar a informação no ficheiro.... (testei um cenário mais puxado e ele deu out of memory)

Como no writeln ele grava logo no ficheiro e não fica com a info na memória talvez seja melhor continuar com este processo...

Obrigado na mesma 😉

Link to comment
Share on other sites

Sim, a maior velocidade da StringList é porque vai guardando em memoria e grava no ficheiro tudo de uma vez.

Ainda tens outra hipotese, embora mais complexa, que é estabelecer um limite na stringlist. Por exemplo, a cada 1000 linhas, ele grava no ficheiro.

Claro que isto implica criar um método "AppendToFile" para a stringlist, mas mesmo assim deve ser mais rapido que usar linha a linha... (só testando para ter certeza)

"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Link to comment
Share on other sites

Agrada-me mais essa última hipótese do "limite". Essencialmente estamos a falar de um buffer para o qual são lidos, por exemplo N KB de strings, são feitas alterações e são escritas no ficheiro de destino.

Uma pergunta: as strings têm todas o mesmo tamanho? Se tiverem isto pode acelerar-se bastante com BlockRead/BlockWrite.

Edited by pwseo
Link to comment
Share on other sites

Não costumo fazer disto por isso pode estar uma asneira tremenda...

Mas pegando no que disseram fiz uma class nova a partir da TStringList e modifiquei de modo ao evento Add guardar as strings até determinado valor e então gravar para o ficheiro.

Mas dado a quantidade de dados não consigo ganhar nada com isto... em todos os cenarios que testei fica mais lento que com o Writeln.

Se eu aumentar muito o numero de strings que guardo antes de enviar para o ficheiro volto ao problema do out of memory.

StringCounter é o limite de strings que quero em memoria antes de enviar para o ficheiro

function StringList.NewAdd(const S: string): Integer;
begin
 Result := AddObject(S, nil);
 inc(_StringCounter);
 if _StringCounter>20000 then
 begin
SaveToFile();
_StringCounter:=0;
 end;
end;

Era assim que estavam a sugerir ou está mal implementado?

Edited by Kline777
Link to comment
Share on other sites

Kline777,

Tens algum exemplo de input que possamos utilizar para ter uma ideia daquilo com que tens que lidar?

Relativamente ao código que colocaste (coloca dentro de tags

 por favor), 20000 strings parece um número razoável e, se pensarmos que cada string tem, habitualmente, 256 bytes, estamos a falar de cerca de 4MB de cada vez.

Penso que para resolver o teu problema temos de conhecer bem o input para saber a forma mais rápida de o ler, alterar e escrever.

Link to comment
Share on other sites

Eu tenho de abrir ficheiros de texto com linhas de coordenadas tipo :

G01X-10.364Y2.127
G01X-9.657Y1.568
G01X-8.896Y1.085
G01X-8.090Y0.683
G01X-7.581Y0.474
G01X-7.063Y0.291
G01X-6.536Y0.133

Nota: O nº de linhas é variavel mas normalmente na casa das 64mil por cada ficheiro e posso ter de abrir cerca de 20 ou 30 ficheiros no mesmo processo.

Depois tenho de separar as coordenadas para as tratar, até aqui penso que está tudo ok, usei uma lista de ponteiros para guardar cada linha e nota-se uma grande diferença de velocidade.

No fim, tenho de escrever o que está na lista com a informção já tratada para o ficheiro final, que será semelhante ao original e neste exemplo

então teria 64mil*20 linhas (gera ficheiros de texto na casa dos 100mb)

Desde o inicio que aqui uso o WriteLn... que funciona porque não fica com a info armazenada na memoria. Pergunto-me é se haverá solução melhor :/

Obrigado

Edited by Kline777
Link to comment
Share on other sites

É natural que não te traga grande melhoria na escrita, porque a escrita é exactamente igual (não escreves mais nem menos caracteres), no entanto deve permitir-te manter mais dados em memória simultaneamente.

Se calhar seria conveniente mostrares parte do código que estás a utilizar para ler, manipular e escrever as strings (se isso não te trouxer problemas, claro).

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.