Página 1 de 5
Copia com barra de progresso.
Enviado: 16 Mai 2013 19:13
por Itamar M. Lins Jr.
Peguei o exemplo em outro forum.
Código: Selecionar todos
#require "xhb"
static nCopiados := 0
static nTotalBytes := 0
function testcopyFile()
local cFile := 'customer.dbf'
local cSource := hb_dirbase() + cFile
local cTarget := 'backup\' + cFile
local lCopy
local aFileInfo := directory( hb_dirbase() + cFile)
nTotalBytes := aFileInfo[1,2] // size file to copy
lCopy := xhb_CopyFile(cSource, cTarget, {| x | ShowCopy( x ) }) // Every 8192 Bytes copied
if !lCopy .or. lCopy == NIL
alert('copy failed')
else
alert('copy done ...')
endif
return nil
function ShowCopy(x)
nCopiados += x
@ 10,10 say ' Copying :' + str(nCopiados) + ' of ' str(nTotalBytes)
return nil
Saudações,
Itamar M. Lins Jr.
Copia com barra de progresso.
Enviado: 17 Mai 2013 11:53
por Jairo Maia
Valeu Itamar,
Apenas uma observação: Esta função retorna .F. se houver falha na cópia, e NIL se a cópia foi bem sucedida. Se o caminho destino não existir ocorre erro em tempo de execução.
Copia com barra de progresso.
Enviado: 23 Mai 2013 17:42
por HASA
:|<
Olá Itamar, será que existe comando similar para xHarbour ? será que alguem sabe ?
:%
HASA
Copia com barra de progresso.
Enviado: 24 Mai 2013 13:07
por Itamar M. Lins Jr.
Tenta usar o fonte da função.
Ou mude para o Harbour caso não use ferramentas que impossibilitem a mudança.
Código: Selecionar todos
/*
* $Id: xhbcopyf.c 18904 2013-03-07 15:13:07Z vszakats $
*/
/*
* Harbour Project source code:
* xhb_CopyFile() function
*
* Copyright 1999 Andi Jahja <andij@aonlippo.co.id>
* www - http://harbour-project.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; see the file COPYING.txt. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
*
* As a special exception, the Harbour Project gives permission for
* additional uses of the text contained in its release of Harbour.
*
* The exception is that, if you link the Harbour libraries with other
* files to produce an executable, this does not by itself cause the
* resulting executable to be covered by the GNU General Public License.
* Your use of that executable is in no way restricted on account of
* linking the Harbour library code into it.
*
* This exception does not however invalidate any other reasons why
* the executable file might be covered by the GNU General Public License.
*
* This exception applies only to the code released by the Harbour
* Project under the name Harbour. If you copy code from other
* Harbour Project or Free Software Foundation releases into a copy of
* Harbour, as the General Public License permits, the exception does
* not apply to the code that you add in this way. To avoid misleading
* anyone as to the status of such modified files, you must delete
* this exception notice from them.
*
* If you write modifications of your own for Harbour, it is your choice
* whether to permit this exception to apply to your modifications.
* If you do not wish that, delete this exception notice.
*
*/
#include "hbapi.h"
#include "hbapierr.h"
#include "hbapifs.h"
#include "hbapiitm.h"
#include "hbvm.h"
#if defined( HB_OS_UNIX )
#include <sys/stat.h>
#include <unistd.h>
#endif
#define BUFFER_SIZE 8192
static HB_BOOL hb_copyfile( const char * szSource, const char * szDest, PHB_ITEM pBlock )
{
HB_BOOL bRetVal = HB_FALSE;
HB_FHANDLE fhndSource;
HB_TRACE( HB_TR_DEBUG, ( "hb_copyfile(%s, %s)", szSource, szDest ) );
while( ( fhndSource = hb_spOpen( szSource, FO_READ | FO_SHARED | FO_PRIVATE ) ) == FS_ERROR )
{
HB_USHORT uiAction = hb_errRT_BASE_Ext1( EG_OPEN, 2012, NULL, szSource, hb_fsError(), EF_CANDEFAULT | EF_CANRETRY, 0 );
if( uiAction != E_RETRY )
break;
}
if( fhndSource != FS_ERROR )
{
HB_FHANDLE fhndDest;
while( ( fhndDest = hb_spCreate( szDest, FC_NORMAL ) ) == FS_ERROR )
{
HB_USHORT uiAction = hb_errRT_BASE_Ext1( EG_CREATE, 2012, NULL, szDest, hb_fsError(), EF_CANDEFAULT | EF_CANRETRY, 0 );
if( uiAction != E_RETRY )
break;
}
if( fhndDest != FS_ERROR )
{
#if defined( HB_OS_UNIX )
struct stat struFileInfo;
int iSuccess = fstat( fhndSource, &struFileInfo );
#endif
HB_BYTE * buffer = ( HB_BYTE * ) hb_xgrab( BUFFER_SIZE );
HB_USHORT usRead;
bRetVal = HB_TRUE;
if( hb_itemType( pBlock ) != HB_IT_BLOCK )
pBlock = NULL;
while( ( usRead = hb_fsRead( fhndSource, buffer, BUFFER_SIZE ) ) != 0 )
{
while( hb_fsWrite( fhndDest, buffer, usRead ) != usRead )
{
HB_USHORT uiAction = hb_errRT_BASE_Ext1( EG_WRITE, 2016, NULL, szDest, hb_fsError(), EF_CANDEFAULT | EF_CANRETRY, 0 );
if( uiAction != E_RETRY )
{
bRetVal = HB_FALSE;
break;
}
}
if( pBlock )
{
PHB_ITEM pCnt = hb_itemPutNL( NULL, usRead );
hb_vmEvalBlockV( pBlock, 1, pCnt );
hb_itemRelease( pCnt );
}
}
hb_xfree( buffer );
#if defined( HB_OS_UNIX )
if( iSuccess == 0 )
fchmod( fhndDest, struFileInfo.st_mode );
#endif
hb_fsClose( fhndDest );
}
hb_fsClose( fhndSource );
}
return bRetVal;
}
/* Clipper returns .F. on failure and NIL on success */
HB_FUNC( XHB_COPYFILE )
{
if( HB_ISCHAR( 1 ) && HB_ISCHAR( 2 ) )
{
if( ! hb_copyfile( hb_parc( 1 ), hb_parc( 2 ), hb_param( 3, HB_IT_BLOCK ) ) )
hb_retl( HB_FALSE );
}
else
hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); /* NOTE: Undocumented but existing Clipper Run-time error */
}
Copia com barra de progresso.
Enviado: 24 Mai 2013 13:55
por HASA
:{ :|<
ITAMAR, FUNCIONOU PERFEITINHO....
:)Pos VALEU MESMO, MUITO OBRIGADO.
HASA
Copia com barra de progresso.
Enviado: 24 Mai 2013 14:28
por HASA
:%
Itamar, agora já abusando um monte tens algo para APPEND FROM () index on ?
8-|
HASA
Copia com barra de progresso.
Enviado: 24 Mai 2013 14:36
por Itamar M. Lins Jr.
Essas até o clipper tem
Código: Selecionar todos
index on mercadoria tag eq03 eval suafuncao(5) every 5
index on ncm tag tm01 eval {||oBar:Set(,Recno()),.t.}
....
oBar := HProgressBar():NewBox( "Importando... "+lTrim(str(1,9))+" De "+lTrim(str(tRec,9))+" Registro(s)",,,400,, tRec, tRec,,.f. )
x := 0
nRec := 0
Append from &string via iif(lRddLeto,"LETO","DBFCDX") For iif(x++==100,(nRec+=x,x:=0,ShowGrafico()),.t.)
oBar : Close()
********************
Function ShowGrafico
********************
hwg_processmessage()
oBar:Set("Importando..."+lTrim(str(nRec,9))+" De "+lTrim(str(tRec,9))+" Registro(s)" ,nRec)
RETURN .T.
Saudações,
Itamar M. Lins Jr.
Copia com barra de progresso.
Enviado: 24 Mai 2013 14:54
por HASA

)
Valeuuu, agora fechou mesmo o assunto.
Mais uma vez obrigado.
:{
Hasa
Copia com barra de progresso.
Enviado: 16 Nov 2013 22:19
por cjp
Meus amigos,
Pesquisando no site, achei este post, que parece trazer justamente o que eu estava precisando: uma barra de progresso para copiar arquivos.
Entretanto, ao testar a função constante do início deste post, está dando erro na linha:
O erro que dá é o seguinte:
Como não conheço a função aFileInfo, e também não achei nada sobre ela no fórum, nem no Google, e como também não entendo bem de array, não consegui entender o erro.
Alguém me ajuda?
Aproveitando, uma outra dúvida: será que tem como usar esta mesma função para copiar todos ou vários arquivos de uma pasta ao mesmo tempo, exibindo a barra de progresso?
Copia com barra de progresso.
Enviado: 17 Nov 2013 00:43
por alxsts
Olá!
O problema está acontecendo porque a pasta de onde você quer copiar o arquivo está vazia...
Na rotina do exemplo, aFileInfo não é uma função e sim uma variável do tipo array, que recebe o retorno da função Directory(), que neste caso, busca o arquivo Customer.dbf na mesma pasta onde está o programa em execução. Como o arquivo não existe na pasta, o array tem 0 elementos e não é possível referenciar um elemento de um array vazio. Faça o teste antes, para saber se o array tem algum elemento:
Código: Selecionar todos
#require "xhb"
static nCopiados := 0
static nTotalBytes := 0
function testcopyFile()
local cFile := 'customer.dbf'
local cSource := hb_dirbase() + cFile
local cTarget := 'backup\' + cFile
local lCopy
local aFileInfo := directory( hb_dirbase() + cFile)
IF Len( aFileInfo ) > 0
nTotalBytes := aFileInfo[1,2] // size file to copy
lCopy := xhb_CopyFile(cSource, cTarget, {| x | ShowCopy( x ) }) // Every 8192 Bytes copied
if !lCopy .or. lCopy == NIL
alert('copy failed')
else
alert('copy done ...')
endif
ENDIF
return nil
Quanto à segunda questão, é perfeitamente possível, adaptando-se a rotina para o que você deseja, e colocando a execução dentro de um laço.
Copia com barra de progresso.
Enviado: 17 Nov 2013 02:03
por cjp
De fato, não tinha observado que era uma variável, desculpe.
Também não tinha observado que a hb_dirbase() retorna pasta diferente de curdir(). Eu estava testando em uma pasta diferente, mudada com dirchange(), mas a hb_dirbase() estava procurando na pasta original do programa. Mas tudo bem, isso eu já resolvi.
Funcionou: copiou e mostrou o progresso. Mas depois de terminada a cópia, tá dando o seguinte erro:
Na seguinte linha:
Mas, desabilitando essa parte final da função, funcionou sem problema.
Estou tentando usar a função para cópia de arquivos de várias pastas. Tentei chamá-la assim:
Código: Selecionar todos
nCopiados := 0
nTotalBytes := 0
testcopyfile("Offline.dbx","c:\mails")
Colocando a função assim:
Código: Selecionar todos
function testcopyFile(cFile,cPasta)
local cSource := cPasta + cFile
local cTarget := '\backup\' + 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
return nil
Mas continua dando o mesmo erro de limite: acesso de array.
Estou fazendo algo errado?
Copia com barra de progresso.
Enviado: 17 Nov 2013 02:29
por alxsts
Olá!
cjp escreveu:Mas continua dando o mesmo erro de limite: acesso de array.
Não colocou o IF para testar se o array tem tamanho maior que zero?
Provavelmente não está retornando nenhum arquivo porque a concatenação de strings que você faz não resulta em um nome de arquivo existente na pasta:
Código: Selecionar todos
testcopyfile("Offline.dbx","c:\mails")
.
.
.
function testcopyFile(cFile,cPasta)
local cSource := cPasta + cFile // cSource recebe "c:\mailsOffline.dbx"
Acrescente uma barra invertida ao segundo parâmetro na chamada da função :
Copia com barra de progresso.
Enviado: 19 Nov 2013 00:55
por cjp
Ok, assim funcionou.
Só não estou conseguindo fazer funcionar com *.*. Estou tentando assim:
Código: Selecionar todos
CopiarArquivo("*.*","c:\backup\",nvpt)
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(1)
return nil
function ShowCopy(x)
nCopiados += x
@10,10 say ' Copiando :' + str(nCopiados) + ' de ' + str(nTotalBytes)
return nil
Será que ele não aceita copiar vários arquivos ao mesmo tempo? Existe outro jeito de fazer isso?
Copia com barra de progresso.
Enviado: 19 Nov 2013 03:51
por alxsts
Olá!
alxsts escreveu: é perfeitamente possível, adaptando-se a rotina para o que você deseja, e colocando a execução dentro de um laço.
Código: Selecionar todos
#include "Directry.ch"
FUNCTION Main()
LOCAL aFileInfo AS Array
LOCAL nItem AS Numeric
LOCAL nCount AS Numeric
LOCAL nTotalBytes AS Numeric := 0
LOCAL lCopy AS Logical := .F.
aFileInfo := DIRECTORY("*.*")
AEval( aFileInfo, { |e| nTotalBytes += e[ F_SIZE ] } )
nCount := Len( aFileInfo )
FOR nItem := 1 TO nCount
lCopy := xhb_CopyFile( aFileInfo[ nItem, F_NAME ], ;
"c:\backup\", ;
{ | aFileInfo[ nItem, F_SIZE ], nTotalBytes | ShowCopy( | aFileInfo[ nItem, F_SIZE ], nTotalBytes ) } ;
) // Size of Every File copied
IF ! lCopy
Alert( "Falha ao copiar arquivo " + aFileInfo[ nItem, F_NAME ] )
BREAK
ENDIF
NEXT
RETURN lCopy
//-----------------------------------------------------------------------------------------
FUNCTION ShowCopy( nCopiados, nTotalBytes )
STATIC nTotalComplete AS Numeric
IF nTotalComplete == NIL
nTotalComplete := 0
ENDIF
nTotalComplete += nCopiados
@10,10 Say ' Copiando :' + LTrim( Str( nTotalComplete ) ) + ' de ' + LTrim( Str( nTotalBytes ) )
RETURN NIL
//-----------------------------------------------------------------------------------------
(Este código ainda não foi compilado e nem testado)
Copia com barra de progresso.
Enviado: 19 Nov 2013 23:57
por cjp
Tá dando erro de sintaxe at '[' na compilação, na seguinte linha:
Código: Selecionar todos
lCopy := xhb_CopyFile( aFileInfo[ nItem, F_NAME ], ;
"c:\backup\", ;
{ | aFileInfo[ nItem, F_SIZE ], nTotalBytes | MostraCopia( | aFileInfo[ nItem, F_SIZE ], nTotalBytes ) } ) // Size of Every File copied
Como não entendo muito bem esse código, não sei onde estaria o erro de sintaxe. Os três grupos de colchete que vejo nesse código (aFileInfo[ nItem, F_NAME ou F_SIZE]) me parecem corretos. Vc me ajuda?