Acelera muchísimo el proceso.
La clase es muy simple de usar y con pocos métodos.
La dejo aquí para que todo el que la mejore la vaya dejando en este hilo.
Ejemplo:
- Code: Select all Expand view RUN
procedure main
local hFile := FCreate( "prueba.txt" )
local o := TFBuffer():new( hFile )
local i, t
cls
@ 10, 10 SAY "Espere, estoy procesando datos..."
t := Seconds()
for i := 1 to 10000000
o:addString( "Esta es la cadena numero: " )
o:addString( Str( i ) )
o:addString( " -> " )
o:addString( Time() )
o:addString( ";" )
o:addString( hb_eol() )
next
t := Seconds() - t
o:free()
FClose( hFile )
// Para calcular el tamaño en kB
hFile := FOpen( "prueba.txt" )
i := FSeek( hFile, 0, 2 ) / 1024
FClose( hFile )
Alert( "Ha tardado: " + AllTrim( Str( t ) ) + " segundos con un fichero de: " + AllTrim( Str( i ) ) + " kB")
return
En mi ordenador genera un fichero de 550.000.000 en solo casi 10 segundos (9.88).
Y esta es la clase:
- Code: Select all Expand view RUN
#include "hbclass.ch"
#define FB_MAX_SIZE 65535
CLASS TFBuffer
DATA hFB // Uso interno
METHOD new( hFile, nLen ) CONSTRUCTOR
METHOD free() // Libera memoria
METHOD creaBuffer( hFile, nLen ) // Uso interno
METHOD addString( cString ) // añade cadena al buffer, hace el ::flush() automaticamente
METHOD flush() // Por si se quiere salvar a disco manualmente
END CLASS
//------------------------------------------------------------------------------
METHOD new( hFile, nLen ) CLASS TFBuffer
if ValType( hFile ) == 'N'
if !( ValType( nLen ) == 'N' .and. nLen > 0 .and. nLen <= FB_MAX_SIZE )
nLen := FB_MAX_SIZE
endif
::creaBuffer( hFile, nLen )
else
Alert( "Al menos deberías meter el manejador de un fichero abierto..." )
endif
return self
//------------------------------------------------------------------------------
#pragma BEGINDUMP
#include "hbapifs.h"
#include "hbapiitm.h"
#include "hbstack.h"
/* Estructura del bufer */
typedef struct
{
unsigned char *pBuffer;
unsigned int uiLen;
unsigned int uiPos;
HB_FHANDLE hFile;
} FBUFFER, *PFBUFFER;
static void _flushFB( PFBUFFER pFB );
//------------------------------------------------------------------------------
// Metodo para crear la estructura buffer
HB_FUNC_STATIC( TFBUFFER_CREABUFFER )
{
PHB_ITEM Self = hb_stackSelfItem();
PFBUFFER pFB = ( PFBUFFER ) hb_xgrab( sizeof( FBUFFER ) );
pFB->uiLen = hb_parnint( 2 );
pFB->pBuffer = ( unsigned char * ) hb_xgrab( pFB->uiLen );
pFB->uiPos = 0;
pFB->hFile = ( HB_FHANDLE ) hb_parnint( 1 );
hb_arraySetPtr( Self, 1, pFB );
}
//------------------------------------------------------------------------------
// Metodo para liberar el buffer
HB_FUNC_STATIC( TFBUFFER_FREE )
{
PHB_ITEM Self = hb_stackSelfItem();
PFBUFFER pFB = hb_arrayGetPtr( Self, 1 );
if( pFB )
{
_flushFB( pFB );
if( pFB->pBuffer )
{
hb_xfree( pFB->pBuffer );
}
hb_xfree( pFB );
}
}
//------------------------------------------------------------------------------
// Metodo para añadir cadenas al buffer
HB_FUNC_STATIC( TFBUFFER_ADDSTRING )
{
PHB_ITEM Self = hb_stackSelfItem();
PFBUFFER pFB = hb_arrayGetPtr( Self, 1 );
PHB_ITEM pString = hb_param( 1, HB_IT_STRING );
if( pString )
{
unsigned int uiPos = 0;
const char *szString = hb_itemGetCPtr( pString );
unsigned int uiLen = hb_itemGetCLen( pString );
while( uiPos < uiLen )
{
if( pFB->uiPos == pFB->uiLen )
{
_flushFB( pFB );
}
pFB->pBuffer[ pFB->uiPos++ ] = ( unsigned char ) szString[ uiPos++ ];
}
}
}
//------------------------------------------------------------------------------
// Metodo para forzar escritura en disco del buffer e inicia la posicion
HB_FUNC_STATIC( TFBUFFER_FLUSH )
{
PHB_ITEM Self = hb_stackSelfItem();
PFBUFFER pFB = hb_arrayGetPtr( Self, 1 );
_flushFB( pFB );
}
//------------------------------------------------------------------------------
// Funcion de uso interno. Escribe en disco el buffer e inicia la posicion
static void _flushFB( PFBUFFER pFB )
{
if( pFB->uiPos > 0 )
{
hb_fsWrite( pFB->hFile, pFB->pBuffer, pFB->uiPos );
pFB->uiPos = 0;
}
}
//------------------------------------------------------------------------------
#pragma ENDDUMP
Como veis está escrita casi toda en lenguaje C
Los métodos son auto descriptivos.
Si la mejoráis, ponerla aquí para que todos podamos usarla.