Copia com barra de progresso.

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

Copia com barra de progresso.

Mensagem por cjp »

De fato, não tinha atentado para esse detalhe, e até demorei um pouco para entender do que vc estava falando. Já acertei e funcionou. E também já excluí as linhas desnecessárias. Muito obrigado.
Inacio de Carvalho Neto
Avatar do usuário
Toledo
Administrador
Administrador
Mensagens: 3133
Registrado em: 22 Jul 2003 18:39
Localização: Araçatuba - SP
Contato:

Copia com barra de progresso.

Mensagem por Toledo »

Bom, então só para complementar:

Código: Selecionar todos

aFileInfo := DIRECTORY(cPOrig+"*.*")
Abraços,
Toledo - Clipper On Line
toledo@pctoledo.com.br
Harbour 3.2/MiniGui/HwGui
Faça uma doação para o fórum, clique neste link: http://www.pctoledo.com.br/doacao
cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

Copia com barra de progresso.

Mensagem por cjp »

Sim, foi exatamente isso que eu fiz e deu certo. Obrigado.
Inacio de Carvalho Neto
cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

Copia com barra de progresso.

Mensagem por cjp »

Colegas,

Usando diariamente esta função, notei uma coisa interessante: a cópia de um arquivo de 1,4 GB, usando o !copy, levou exatos 7 minutos e 23 segundos. Já o mesmo arquivo copiado com esta função xhb_copyfile() levou exatos 22 minutos e 22 segundos. Ou seja, cerca de 3 vezes mais.

Isso é normal? Tem alguma razão para ser tão mais lento? Existe alguma solução para isso?
Inacio de Carvalho Neto
cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

Copia com barra de progresso.

Mensagem por cjp »

Alguém saberia me dizer se tem alguma razão de demorar tanto assim a cópia desse jeito?
Inacio de Carvalho Neto
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Copia com barra de progresso.

Mensagem por JoséQuintas »

Tudo depende do seu gráfico.
Só imaginar que a cada byte copiado a função vai ser chamada.
E atualização de tela é mais demorada que cópia.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

Copia com barra de progresso.

Mensagem por cjp »

Hum, e será que tem como chamar a função menos vezes?

Minha função está assim:

Código: Selecionar todos

function CopiarArquivo(cFile,cPasta,cPDest)
 local cSource := cPasta + cFile
 local cTarget := cPDest + cFile
 local lCopy
 local aFileInfo := directory( cPasta + cFile)
 nTotalBytes := aFileInfo[1,2] // size file to copy
 lCopy := xhb_CopyFile(cSource, cTarget, {| x | ShowCopy( x ) }) // Every 8192 Bytes copied
 inkey(5)
return .t.

function ShowCopy(x)
 nCopiados += x
 @ maxrow()-1,1 say ' Copiando :' + str(nCopiados/1048576) + ' de ' + str(nTotalBytes/1048576) + " Mb"
return nil

Quem sabe poderia atualizar a cada 10 Mb, por exemplo, para acelerar a função.
Inacio de Carvalho Neto
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Copia com barra de progresso.

Mensagem por JoséQuintas »

Eu uso um estilo padrão, pra atualizar tela a cada 1 segundo.
Faça o teste se ajuda.

Código: Selecionar todos

FUNCTION ShowGrafico()
   STATIC cTime := "XX"

   IF cTime == Time()
       RETURN NIL
   ENDIF
   cTime := Time()
   // mostra grafico
   RETURN NIL
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

Copia com barra de progresso.

Mensagem por cjp »

Desculpem a demora, estive afastado e só agora retornei.

Fiz vários testes, mas aparentemente não é esse o problema.

Testando com um arquivo de 930 MB, se coloco para atualizar a cada 5 segundos, demorou 9 minutos e 32 segundos; se coloco para atualizar a cada 10 segundos, demorou 9 minutos e 27 segundos. Mas copiando com o !copy, demorou apenas 3 minutos e 24 segundos.

Será que o problema não está na própria xhb_copyfile()?
Inacio de Carvalho Neto
Avatar do usuário
Toledo
Administrador
Administrador
Mensagens: 3133
Registrado em: 22 Jul 2003 18:39
Localização: Araçatuba - SP
Contato:

Copia com barra de progresso.

Mensagem por Toledo »

cjp escreveu:// Every 8192 Bytes copied
Como é observado no exemplo de uso da função xhb_CopyFile(), o arquivo é copiado a cada 8192 bytes. Então para acelerar a função poderia tentar aumentar o número de bytes copiados, mas para fazer isto você teria que ter os arquivos fontes da LIB xhb (pasta ..\CONTRIB\XHB) e editar o arquivo xhbcopyf.c, modificando o valor da variável BUFFER_SIZE:

Código: Selecionar todos

#define BUFFER_SIZE 8192
Você pode duplicar o valor, por exemplo: #define BUFFER_SIZE 16384

Depois é só recompilar a LIB novamente.

Abraços,
Toledo - Clipper On Line
toledo@pctoledo.com.br
Harbour 3.2/MiniGui/HwGui
Faça uma doação para o fórum, clique neste link: http://www.pctoledo.com.br/doacao
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Copia com barra de progresso.

Mensagem por JoséQuintas »

Aproveitando o gancho...
A lentidão no uso de DBFs é exatamente pelo mesmo motivo: o tamanho do "buffer" vai ser o tamanho do registro.
Então um relatório, ou um set filter, fica lento principalmente em rede.
Mesmo que a rede seja gigabit, a transferência vai ser por blocos pequenos.

É nisso que o servidor de banco de dados também ganha do dbf: Transfere em blocos maiores.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

Copia com barra de progresso.

Mensagem por cjp »

Toledo, como faço para recompilar a lib?

Desculpe minha ignorância, mas nunca fiz isso.
Inacio de Carvalho Neto
Avatar do usuário
Toledo
Administrador
Administrador
Mensagens: 3133
Registrado em: 22 Jul 2003 18:39
Localização: Araçatuba - SP
Contato:

Copia com barra de progresso.

Mensagem por Toledo »

cjp, primeiramente você tem que ter os código fontes da LIB, então verifique se na pasta ..\CONTRIB\XHB do seu Harbour tem o arquivo xhbcopyf.c.

Se o arquivo xhbcopyf.c existir, para recompilar basta seguir as orientações do arquivo INSTALL que está na pasta principal do seu Harbour:
2. HOW TO DO A PARTIAL [RE]BUILD
================================

If you want to [re]build only a specific part of Harbour, like
one core library or all core libraries, or all contrib packages,
you have to do everything the same way as for a full build, the
only difference is that you first have to go into the specific
source directory you want to [re]build. When starting GNU Make,
all components under that dir will be [re]built:

cd src/rtl
<make> [clean] [install]

If you want to rebuild one specific contrib package, use this:

cd contrib/<name>
../../bin/<plat>/<comp>/hbmk2 ../make.hb [clean] [custom hbmk2 options]
Conforme orientação acima, você teria que entrar na pasta ..\CONTRIB\XHB do seu Harbour e digitar:

HBMK2 ../make.hb clean

Abraços,
Toledo - Clipper On Line
toledo@pctoledo.com.br
Harbour 3.2/MiniGui/HwGui
Faça uma doação para o fórum, clique neste link: http://www.pctoledo.com.br/doacao
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7929
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

Copia com barra de progresso.

Mensagem por Itamar M. Lins Jr. »

Aproveitando o gancho...
A lentidão no uso de DBFs é exatamente pelo mesmo motivo: o tamanho do "buffer" vai ser o tamanho do registro.
Então um relatório, ou um set filter, fica lento principalmente em rede.
Mesmo que a rede seja gigabit, a transferência vai ser por blocos pequenos.

É nisso que o servidor de banco de dados também ganha do dbf: Transfere em blocos maiores.
Isso pode ser corrigido, porém tem uma coisa mais importante que é o Harbour 32 e outro Harbour 64, segundo o Pzmek o ganho de velocidade é bem maior, desde que todas as rotinas estejam ajustadas para 64bits! e o Harbour já pode ser compilado em 64Bits.
Hi,

> Would an application compiled as 64 bit by Harbour operate faster on
> a 64 bit machine vs the same application compiled as 32 bit on the
> same 64 bit machine?

Yes it will. Mostly due to the cost of switching between kernel and
user space. In 64 bit mode we have extremely huge address space so
it's possible to set fixed addresses for user space and kernel space
and never reload memory descriptors when execution context is changed.
Here depending on the OS and type of application )how many times
system functions are called) the speed difference can be quite huge.
Additional speed up is also reached due to wider set of machine
instructions and completely new C ABI which uses extended 64-bit
registers to pass parameters when C functions are called. This
gives about 10-15% speed improvement in case of Harbour HVM.

best regards,
Przemek
Então não é porque usamos DBF e sim por causa da arquitetura adotada, cliente servidor é o que deve ser adotado.
Olhe o custo do ADS por exemplo que usa DBF e é extremamente rápido inclusive com uso de sintaxe SQL.
Ou então olhe esse código do Letodb que é executado do lado do servido, simulando o (foreign key)

Código: Selecionar todos

/*
 * UDF_UpdCascade - cascade update key fields in main and relation table
 * Parameters:
 *   nRecNo       - record number in the main table
 *   cKeyField    - field name in the main table (primary key)
 *   xKeyNew      - new value of key field
 *   cClientAlias - client alias of the relation table
 *   cKeyField2   - field name in the relation table (foreign key)
 *   xOrder       - order name or order number in the relation table
 *
 * This function return array of record buffer in two tables
 * Call from client:
 *
 * aRecBuf := Leto_Udf("UDF_UpdCascade", ... )
 * (table1)->( leto_ParseRec( aRecBuf[1] ) )
 * (table2)->( leto_ParseRec( aRecBuf[2] ) )
 */
FUNCTION UDF_UpdCascade( nUserStru, nRecNo, cKeyField, xKeyNew, cClientAlias, cKeyField2, xOrder )
   LOCAL xKeyOld, cLetoAlias, cArea := Alias()
   LOCAL nPos := FieldPos( cKeyField ), nPos2
   LOCAL cRecBuf1, cRecBuf2

   dbGoto( nRecNo )
   xKeyOld := FieldGet( nPos )
   IF xKeyOld != xKeyNew .and. leto_RecLock( nUserStru, nRecNo )
      FieldPut( nPos, xKeyNew )
      leto_RecUnlock( nUserStru, nRecNo )
      cRecBuf1 := leto_rec( nUserStru )

      cLetoAlias := leto_Alias( nUserStru, cClientAlias )
      dbSelectArea( cLetoAlias )
      IF Empty( cKeyField2 )
         cKeyField2 := cKeyField
      ENDIF
      nPos2 := FieldPos( cKeyField2 )
      IF ! Empty( xOrder )
         ordSetFocus( xOrder )
      ENDIF
      WHILE dbSeek( xKeyOld )
         IF leto_RecLock( nUserStru, RecNo() )
            FieldPut( nPos2, xKeyNew )
            leto_RecUnlock( nUserStru, RecNo() )
         ELSE
            EXIT
         ENDIF
      ENDDO
      dbSeek( xKeyNew )
      cRecBuf2 := leto_rec( nUserStru )

      dbSelectArea( cArea )

   ENDIF
   RETURN { cRecBuf1, cRecBuf2 }
Se usarmos em uma REDE sem servidor, provavelmente ficaria muito lento e perigoso, porém este código é executado no servidor, pelo "DAEMON" letodb
E também podemos usar um servidor LINUX via SSH, que fica muito rápido e corrupção de DBF´s praticamente 0%.


Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

Copia com barra de progresso.

Mensagem por cjp »

Toledo, não tenho o arquivo xhbcopyf.c na pasta contrib\xhb. Como faço para obtê-lo?
Inacio de Carvalho Neto
Responder