Kline777 Posted August 21, 2012 at 05:08 PM Report Share #473055 Posted August 21, 2012 at 05:08 PM 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 More sharing options...
nunopicado Posted August 21, 2012 at 05:12 PM Report Share #473058 Posted August 21, 2012 at 05:12 PM 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 More sharing options...
Kline777 Posted August 22, 2012 at 08:28 AM Author Report Share #473115 Posted August 22, 2012 at 08:28 AM 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 More sharing options...
nunopicado Posted August 22, 2012 at 08:33 AM Report Share #473116 Posted August 22, 2012 at 08:33 AM 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 More sharing options...
pwseo Posted August 22, 2012 at 12:34 PM Report Share #473136 Posted August 22, 2012 at 12:34 PM (edited) 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 August 22, 2012 at 12:39 PM by pwseo Link to comment Share on other sites More sharing options...
Kline777 Posted August 22, 2012 at 05:07 PM Author Report Share #473173 Posted August 22, 2012 at 05:07 PM Ando de volta disto no trabalho mas entretanto outras prioridades surgiram... quando puder vou voltar a tentar e dou aqui algum feedback 😉 Obrigado Link to comment Share on other sites More sharing options...
Kline777 Posted August 28, 2012 at 10:26 AM Author Report Share #473772 Posted August 28, 2012 at 10:26 AM (edited) 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 August 28, 2012 at 02:18 PM by Kline777 Link to comment Share on other sites More sharing options...
pwseo Posted August 28, 2012 at 02:02 PM Report Share #473801 Posted August 28, 2012 at 02:02 PM 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 More sharing options...
Kline777 Posted August 28, 2012 at 02:24 PM Author Report Share #473807 Posted August 28, 2012 at 02:24 PM (edited) 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 August 28, 2012 at 02:27 PM by Kline777 Link to comment Share on other sites More sharing options...
pwseo Posted August 28, 2012 at 02:29 PM Report Share #473810 Posted August 28, 2012 at 02:29 PM Tentaste impor alguma restrição no tamanho das strings armazenadas? Porque se estás a utilizar strings "simples", estás a desperdiçar imensos bytes de memória. Repara que nesse exemplo que deste, cada linha tem menos de 20 caracteres. Link to comment Share on other sites More sharing options...
Kline777 Posted August 28, 2012 at 02:56 PM Author Report Share #473815 Posted August 28, 2012 at 02:56 PM Tentei agora e não me trouxe grande melhoria na escrita usando o writeln, mas vou manter porque é boa prática. Depois vou voltar à stringlist com esta restrição a ver se ele não estoira a memória novamente. Obrigado 😉 Link to comment Share on other sites More sharing options...
pwseo Posted August 28, 2012 at 02:59 PM Report Share #473816 Posted August 28, 2012 at 02:59 PM É 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 More sharing options...
Kline777 Posted September 4, 2012 at 04:31 PM Author Report Share #474477 Posted September 4, 2012 at 04:31 PM É complicado estar a por isso aqui :/ Já consegui acelerar bastante o processo e até o cliente ficou todo contente... portanto por agora está bom ^^ Obrigado pela ajuda 😉 Link to comment Share on other sites More sharing options...
pwseo Posted September 4, 2012 at 04:56 PM Report Share #474480 Posted September 4, 2012 at 04:56 PM Sim, por isso disse para o fazeres apenas se não te causasse problemas 🙂 No entanto, seria bom se colocasses aqui a solução que encontraste (não precisa de ser muito reveladora) para futuros utilizadores com problemas semelhantes 🙂 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now