#include "hbclass.ch"
CLASS TBuffer
DATA nSize INIT 4096
DATA cBuffer
DATA nCurLen
DATA bProcess
METHOD New( nLen ) CONSTRUCTOR
METHOD Out( cText )
METHOD End() DESTRUCTOR
ENDCLASS
METHOD New( nLen, bProcess ) CLASS TClassA
IF ValType( nLen ) == 'N'
::nSize:= nLen
ENDIF
::cBuffer:=""
::nCurLen:= 0
::bProcess:= bProcess
RETURN Self
METHOD Out( cText )
IF ::nCurLen + Len( cText ) > ::nSize
::bProcess:Eval( ::cBuffer, ::nCurLen )
::nCurLen:= 0
::cBuffer:= ""
ENDIF
::cBuffer+= cText
::nCurLen+= Len(cText)
RETURN Self
METHOD End()
IF ::nCurLen > 0
::bProcess:Eval( ::cBuffer, ::nCurLen )
ENDIF
RETURN NIL
hmpaquito wrote:Mi sorpresa fue cuando después de ponerle un buffer de 60.000 los tiempos de grabación con fwrite (menos) se mantienen practicamente iguales.
¿ No será muy costoso, en tiempo, casi como un fwrite() un bucle concatenario del estilo cLine+= cText ?
PD 1. ¿ No seria más rapido crear el fichero en memoria y tratarlo con fwrite ?
PD 2. El txt que creo, ahora mismo, tiene ~ 130 mb y tarda 4 h.
xmanuel wrote:Segú lo que sea te podré ayudar
#Define nBUFFER_SIZE 4096
nH:= FCreate("Clientes.Txt")
cLin:= ""
SELECT Clientes
GO TOP
DO WHILE !Eof()
// Aqui es donde se deteriora la memoria, especialmente con buffer de gran tamaño.
cLin+= FIELD-> Codigo+ ";"+ FIELD-> Nombre+ ";"+ FIELD-> Direccion+ ";"+ FIELD-> Poblacion+ ";"+ FIELD-> Provincia+ ";"+ FIELD-> Observaciones+ CRLF
If Len(cLin) >= nBUFFER_SIZE
FWrite(nH, cLin)
cLin:= ""
ENDIF
SKIP
ENDDO
FWrite(nH, cLin)
FClose(nH)
mibuffer := creaBuffer()
SELECT Clientes
GO TOP
DO WHILE !Eof()
escribeEnBuffer( mibuffer, FIELD-> Codigo )
escribeEnBuffer( mibuffer, ";" )
escribeEnBuffer( mibuffer, FIELD-> Nombre)
escribeEnBuffer( mibuffer, ";" )
escribeEnBuffer( mibuffer, FIELD-> Direccion)
escribeEnBuffer( mibuffer, ";" )
escribeEnBuffer( mibuffer, FIELD-> Poblacion)
escribeEnBuffer( mibuffer, ";" )
escribeEnBuffer( mibuffer, FIELD-> Provincia)
escribeEnBuffer( mibuffer, ";" )
escribeEnBuffer( mibuffer, FIELD-> Observaciones)
escribeEnBuffer( mibuffer, CRLF )
SKIP
ENDDO
freeBuffer( mibuffer )
xmanuel wrote:La idea es crea un buffer de memoria fijo que escriba en el fichero de destino cuando se llene.
Y de eso se tiene que encargar el propio gestor del buffer.
El ancho del buffer yo lo pondría lo más grande posible (lo que permita FWrite())
xmanuel wrote:Si me dejais hasta el fin de semana lo hago
hmpaquito wrote:Pondré un buffer más pequeño para intentar guardar un equilibrio entre tamaño de buffer y numero de fwrites.
Volveré por aquí a informar del resultado.
The txt that I believe, right now, has ~ 130 mb and takes 4 h.
DBF2TEXT( bWhile, bFor, aFields, cDelim, hFile, cSep, nCount, cdp )
04-05-2018 18:46 142,527,000 customer.txt
1 File(s) 142,527,000 bytes
USE CUSTOMER
hFile := FCreate( "customer.txt" )
? "start"
nSecs := SECONDS()
for n := 1 to 2200
CUSTOMER->( DBGOTOP() )
CUSTOMER->( DBF2TEXT( nil, nil, nil, nil, hFile, ";", -1 ) )
next
FClose( hFile )
? SECONDS() - nSecs
Return to FiveWin para Harbour/xHarbour
Users browsing this forum: Google [Bot], nageswaragunupudi and 61 guests