Yo hice una prueba antes, e intenté hacer una optimización, leyendo el máximo permitido por FREAD( 65535 bytes) y guardando en una variable hasta 256 pedazos (16 MB, el máximo de una variable) y luego guardando en destino con FWRITE que increiblemente no tiene ese límite de 65535, y la verdad es que esa prueba me dejó mal sabor...
Puse un wait windows nowait "Leyendo..." y uno para el "Escribiendo...", y no podía creer que la lectura de los 16 MB se tardaba como 5 segundos y la escritura de lo mismo era casi instantánea! ¿una escritura más rápida que una lectura? Así que luego hice un SET COVERAGE TO <archivo> para analizar el programa y ver dónde se iban los tiempos, que no me lo podía creer, y efectivamente, se iba en el FREAD.
Este es el programa, por si a alguno le interesa:
*-- Fernando D. Bozzo
*-- 24/07/2014
LPARAMETERS tcOrigen, tcDestino
TRY
LOCAL lnHandle_O, lnHandle_D, lcStr, laDir(1,1), I, lnSecs, loEx as Exception
IF EMPTY(tcOrigen)
tcOrigen = 'C:\DESA\CORRUPCION_TABLAS\corrupcion.zip'
ENDIF
IF EMPTY(tcDestino)
tcDestino = 'C:\DESA\CORRUPCION_TABLAS\corrupcion.zip.2'
ENDIF
IF ADIR( laDir, tcOrigen ) = 0
ERROR 1, tcOrigen
ENDIF
IF laDir(1,2) = 0
lnHandle_D = FCREATE( tcDestino, 0 )
FCLOSE(lnHandle_D)
EXIT
ENDIF
SET COVERAGE TO (FULLPATH('copyfile.log'))
lnSecs = SECONDS()
lnHandle_O = FOPEN( tcOrigen, 0 )
lcStr = ''
IF lnHandle_O > -1 THEN
lnHandle_D = FCREATE( tcDestino, 0 )
DO WHILE NOT FEOF( lnHandle_O )
WAIT WINDOW NOWAIT 'Leyendo...'
FOR I = 1 TO 256
lcStr = lcStr + FREAD( lnHandle_O, 65535 )
IF FEOF( lnHandle_O )
EXIT
ENDIF
ENDFOR
WAIT WINDOW NOWAIT 'Escribiendo...'
FWRITE( lnHandle_D, lcStr )
lcStr = ''
ENDDO
ENDIF
CATCH TO loEx
MESSAGEBOX( loEx.Message )
FINALLY
FCLOSE(lnHandle_O)
FCLOSE(lnHandle_D)
SET COVERAGE TO
WAIT WINDOW NOWAIT "Tiempo de copia: " + TRANSFORM(SECONDS()-lnSecs) + " segundos"
ENDTRY
RETURN
Y este el análisis del log con el Coverage Profiler:
*-- Fernando D. Bozzo
*-- 24/07/2014
LPARAMETERS tcOrigen, tcDestino
0 Hits 1st 0.000000 Avg 0.000000 TRY
0 Hits 1st 0.000000 Avg 0.000000 LOCAL lnHandle_O, lnHandle_D, lcStr, laDir(1,1), I, lnSecs, loEx as Exception
0 Hits 1st 0.000000 Avg 0.000000 IF EMPTY(tcOrigen)
0 Hits 1st 0.000000 Avg 0.000000 tcOrigen = 'C:\DESA\CORRUPCION_TABLAS\corrupcion.zip'
ENDIF
0 Hits 1st 0.000000 Avg 0.000000 IF EMPTY(tcDestino)
0 Hits 1st 0.000000 Avg 0.000000 tcDestino = 'C:\DESA\CORRUPCION_TABLAS\corrupcion.zip.2'
ENDIF
0 Hits 1st 0.000000 Avg 0.000000 IF ADIR( laDir, tcOrigen ) = 0
0 Hits 1st 0.000000 Avg 0.000000 ERROR 1, tcOrigen
ENDIF
0 Hits 1st 0.000000 Avg 0.000000 IF laDir(1,2) = 0
0 Hits 1st 0.000000 Avg 0.000000 lnHandle_D = FCREATE( tcDestino, 0 )
0 Hits 1st 0.000000 Avg 0.000000 FCLOSE(lnHandle_D)
0 Hits 1st 0.000000 Avg 0.000000 EXIT
ENDIF
0 Hits 1st 0.000000 Avg 0.000000 SET COVERAGE TO (FULLPATH('copyfile.log'))
1 Hit 1st 0.000184 Avg 0.000184 lnSecs = SECONDS()
1 Hit 1st 0.000622 Avg 0.000622 lnHandle_O = FOPEN( tcOrigen, 0 )
1 Hit 1st 0.000062 Avg 0.000062 lcStr = ''
1 Hit 1st 0.000046 Avg 0.000046 IF lnHandle_O > -1 THEN
1 Hit 1st 0.020831 Avg 0.020831 lnHandle_D = FCREATE( tcDestino, 0 )
1 Hit 1st 0.000059 Avg 0.000059 DO WHILE NOT FEOF( lnHandle_O )
13 Hits 1st 0.004293 Avg 0.002155 WAIT WINDOW NOWAIT 'Leyendo...'
13 Hits 1st 0.000654 Avg 0.000108 FOR I = 1 TO 256
3106 Hits 1st 0.000305 Avg 0.012421 lcStr = lcStr + FREAD( lnHandle_O, 65535 )
3106 Hits 1st 0.000002 Avg 0.000137 IF FEOF( lnHandle_O )
1 Hit 1st 0.000030 Avg 0.000030 EXIT
ENDIF
3105 Hits 1st 0.000039 Avg 0.000053 ENDFOR
13 Hits 1st 0.001731 Avg 0.001573 WAIT WINDOW NOWAIT 'Escribiendo...'
13 Hits 1st 0.052120 Avg 0.050576 FWRITE( lnHandle_D, lcStr )
13 Hits 1st 0.002155 Avg 0.002005 lcStr = ''
13 Hits 1st 0.000053 Avg 0.000089 ENDDO
ENDIF
1 Hit 1st 0.000000 Avg 0.000000 CATCH TO loEx
0 Hits 1st 0.000000 Avg 0.000000 MESSAGEBOX( loEx.Message )
1 Hit 1st 0.000027 Avg 0.000027 FINALLY
1 Hit 1st 0.001880 Avg 0.001880 FCLOSE(lnHandle_O)
1 Hit 1st 0.012949 Avg 0.012949 FCLOSE(lnHandle_D)
1 Hit 1st 0.000042 Avg 0.000042 SET COVERAGE TO
0 Hits 1st 0.000000 Avg 0.000000 WAIT WINDOW NOWAIT "Tiempo de copia: " + TRANSFORM(SECONDS()-lnSecs) + " segundos"
0 Hits 1st 0.000000 Avg 0.000000 ENDTRY
0 Hits 1st 0.000000 Avg 0.000000 RETURN
Me llamó mucho la atención que solo el primer FREAD fuera rápido (0.000305 segundos) y que la media fuera de 0.012 segundos (demasiado)
O sea, para el archivo que usé de prueba (unos 200 MB):
- Tiempo de lectura: 3106 hits * 0.012421 segs = 38,579626 segundos
- Tiempo de escritura: 13 hits * 0.05212 segs = 0,67756 segundos
En fin, luego de ver esto (que me tardó como 10 veces más que el COPY), creo que es mejor un COPY FILE de Fox por archivo y llevar el progreso por archivo.