FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
||||
|
||||
Cual la capacidad de un TStringList?
Hola a todos mi duda es si el TStringList tiene alguna limitacion en cuanto al tamaño (o numero de lineas) del archivo con el que trabaja. Mi problema es que tengo una rutina que carga datos desde un archivo de texto a una tabla DBF y hasta ahora el archivo de texto no pasaba los 1.3 MB (como 29mil registros que tarda mas de 10 min) asi que mi rutina funciona bien, pero se presento que el archivo que necesito cargar es de aprox. 6MB con algo mas de 80mil registros. Mi rutina a parte de que tarda un monton, se corta a medias y no se por que.
este es mi codigo (algo resumido): se puede hacer esto de otra manera cosa que acepte archivos de texto bastante grandes y que el proceso no tarde mucho? |
#2
|
||||
|
||||
para quien le entienda
>Hello,
>>Someone knows the exact limits of TStringList.LoadFromFile ? >>- file size ? >- max lines ? >- ctrl_Z in file ? >>(I know it stops on nulls). I don't think there should be specific filesize or maxline limits other than those that are imposed by the process. LoadFromFile calls LoadFromStream which calls Read which calls HandleStream.Read which calls FileRead which returns a pointer to a buffer and a count of the bytes read ( a DWORD so there is a 2gb or is it 4gb limit there). the Tstrings.LoadFromStream looks like Size := Stream.Size - Stream.Position; SetString(S, nil, Size); Stream.Read(Pointer(S)^, Size); SetTextStr(S); so it is clear that there is a 1 hit read of all the data on that file until the end of file (which might not be what you want if you have other stuff on the file). Anyway, all the data goes into an ansistring S (which is local and will be deallocated on exit) but afaik the memory for the underlying buffer is never freed until the handle is finally freed .. this seems wasteful (as in, as soon as we have finished the load we could release the file buffer .. but I may have misread the code). Next we have SetTextStr which is a loop that looks like so P := Pointer(Value); if P <> nil then while P^ <> #0 do begin Start := P; while not (P^ in [#0, #10, #13]) do Inc(P); SetString(S, Start, P - Start); Add(S); if P^ = #13 then Inc(P); if P^ = #10 then Inc(P); end; (I am sure Borland will forgive me for publishing this code snippet, in the interests of science). So, there are some possibilities of some oddities here particularly wrt #0,#10,#13. The #10 and #13 were put there by GetTextStr .. but you might have had them embedded in your original source strings. The #0 .. again, you may have had a reason for having one or more consecutive empty strings in your original list. Note also the call to Add .. depending upon your settings of Sorted and, if sorted, Duplicates this can end up with another call to the bsearch find and Insert (even if you KNOW you are restoring a sorted list), and some locale dependencies. My point is that TstringList.SaveToFile and LoadFromFile are not the simple mirror image dump and restore of blocks of characters that one might expect. There is quite a lot of looping and comparison and memory management going on under the hood, so if your strings have unusual content or you need to do a lot of this ,you might be better off considering alternative structures. fwiw |
#3
|
|||
|
|||
Acabo de probar de cargar un archivo de 10Mb en un TStringList y no tuve ningún problema.
EDIT: Vos lo explicaste mejor. |
#4
|
||||
|
||||
otro tip
gracias Alvaro por tu interes, tal vez se deba a algun 'error' en el archivo de texto, de todos modos mi pregunta es si cargaste el archivo de 10Mb en el TStringList y lo recorriste? o solo lo cargaste?
acerca de mi otra duda de por que me demora tanto la carga y al tener en mi codigo una llamada repetitiva del ProcessMessages encontre este comentario: In your loop you need to add a call to the Application.ProcessMessages method. This will allow your application to process Windows messages, including those generated by user actions. There are two significant caveats. First, since Windows messages often translate into calls to event handlers your program may begin to do things at inappropriate times. Make sure that the user can't initiate actions that will interfere with the loop while the loop is active. In particular, note the following sentence, taken from Delphi 3's help file on TApplication.Terminated: "For applications using calculation-intensive loops, call Application.ProcessMessages periodically, and also check Application.Terminated to determine whether or not to abort the calculation so that the application can terminate." The second caveat is that calling Application.ProcessMessages can be relatively expensive and may slow the program. In a fast (tight) loop you may not want to call the method on each iteration. If you only want to update the display and not handle user input you can use the Update method (Delphi 3 and up) of the control covering the part of the display you want to update. Remember that this will also slow down the loop! Última edición por halcon_rojo fecha: 12-04-2006 a las 22:02:33. |
#5
|
|||
|
|||
Exacto, eso que remarcaste en rojo es correcto, tal vez sería mejor llamar a Application.ProcessMessages cada X cantidad de registros procesados, no cada 1.
|
#6
|
|||
|
|||
Hola.
Me estuve leyendo el fragmento que esta en ingles pues casualmente soy uno de los que tiene el problema con el caracter #0. Me estaba ocurriendo que cuando leia el archivo con LoadFromFile y dicho archivo contenia en algun lugar el caracter #0 se me cortaba ahi el archivo no seguia cargando. Quizas la solucion del problema le sea util a alguien y aqui se las dejo. En el fuente solamente lo que hice fue cambiar el caracter #0 que venia por un caracter A, quizas en otras aplicaciones se deba hacer otra cosa pero creo que el ejemplo vale.
Ah y la llamada y creacion del nuevo componente muy facil.
Otra variante pudo ser redefinir el metodo SetTextStr en lugar de loadfromstream Por cierto he cargado archivos de mas de 100MBytes con ese codigo Espero que sea de utilidad a alguien. Saludos Juan Carlos Última edición por JCarlosas fecha: 16-05-2006 a las 01:47:44. |
|
|
Temas Similares | ||||
Tema | Autor | Foro | Respuestas | Último mensaje |
Capacidad de Paradox | irvingcm | Tablas planas | 3 | 13-04-2005 00:41:59 |
Cual es el limite de capacidad de Paradox? | URBANO | Tablas planas | 1 | 15-03-2005 09:54:12 |
Saber exactamente cual es cual en un DBLookUpComboBox | bustio | OOP | 3 | 03-02-2005 23:16:58 |
Capacidad del QReport | marila | Impresión | 2 | 22-04-2004 16:02:47 |
Capacidad No soportada con BDE | GIVO | Conexión con bases de datos | 3 | 27-08-2003 03:10:09 |
|