f



COPY('*.std','stdfiles.clm')

COPY('*.std','stdfiles.clm')

How can I do something like this in Clarion?  API?

Need to copy multiple files into a single file like you can in DOS.

Thanks!
Greg Berthume


0
greg3760 (74)
7/16/2003 6:18:53 PM
comp.lang.clarion 5469 articles. 4 followers. Post Follow

14 Replies
661 Views

Similar Articles

[PageSpeed] 0

Was hoping there was an easier way...

I could always use PowerRUN and a hidden DOS window but processing within
Clarion is probably safer.

Thanks.

"Randy Goodhew" <rgoodhew@fuse.net> wrote in message
news:3F1598D6.DBFB311D@fuse.net...
> Assuming you want to concatenate multiple files,
> use the DOS database driver and APPEND to a master file.
>
> Greg Berthume wrote:
> >
> > COPY('*.std','stdfiles.clm')
> >
> > How can I do something like this in Clarion?  API?
> >
> > Need to copy multiple files into a single file like you can in DOS.
> >
> > Thanks!
> > Greg Berthume
>
> -- 
>  Randy Goodhew
>  ---[ eQ ]---


0
greg3760 (74)
7/16/2003 6:44:10 PM
> COPY('*.std','stdfiles.clm')
>
> How can I do something like this in Clarion?  API?
>
> Need to copy multiple files into a single file like you can in DOS.

Here's some code I whipped up that does the job if anybody else needs it.
Make sure you add the DOS driver to your app/project.

! Procedure Declaration:

MFileCopy               PROCEDURE(STRING pFolder, STRING pFiles, STRING
pDestFile, BYTE pFlag, BYTE pEraseFile),LONG

! Globals

gDestFile                 CSTRING(128)
gCFile                    CSTRING(FILE:MaxFilePath)

! Usage Example:

  E# = MFileCopy('c:\temp','*.asc','ascfiles.sav',1,1)
  IF E#
     STOP('MFileCopy Error: ' & E#)
  END
  STOP('MFileCopy Completed')


!---------------------------------------------------------------------------
-------------------------------!
MFileCopy PROCEDURE(STRING pFolder, STRING pFiles, STRING pDestFile, BYTE
pFlag, BYTE pEraseFile)
!---------------------------------------------------------------------------
-------------------------------!

CFile     FILE,DRIVER('DOS'),NAME(gCFile),PRE(CFL),CREATE
Record    RECORD,PRE()
Chunk        STRING(128)
          END
    END

DFile     FILE,DRIVER('DOS'),NAME(gDestFile),PRE(DFL),CREATE
Record    RECORD,PRE()
Chunk        STRING(128)
          END
    END

lFolder         CSTRING(FILE:MaxFilePath)
lFiles          CSTRING(20)
lFlag           BYTE
lEraseFile      BYTE

CFileQ          QUEUE(FILE:Queue),PRE(CFQ)
    END

CopyWindow WINDOW,AT(,,148,45),FONT('Tahoma',10,,),CENTER,GRAY,DOUBLE
       IMAGE('cmspackage.ico'),AT(6,12),USE(?Image1)
       STRING('Copying File
To ->'),AT(29,4),USE(?TransferString),TRN,FONT('Tahoma',10,,FONT:regular)
       STRING(@s12),AT(92,4),USE(gDestFile)
       PROGRESS,USE(?ProgressBar),AT(29,16,113,10),RANGE(0,100)
       STRING('File:'),AT(29,31),USE(?String4)
       STRING(@s20),AT(46,31,,10),USE(CFQ:ShortName)
     END


CODE

  lFolder   = pFolder
  lFiles    = pFiles
  gDestFile = pDestFile
  lFlag     = pFlag       ! True if the DestFile needs to be deleted if
exists.
  lEraseFile= pEraseFile  ! True if erase source file after copying to
gDestFile?

  SETPATH(lFolder)
  IF ERRORCODE()
     BEEP(BEEP:SystemExclamation)  ;  YIELD()
     MESSAGE('The specified folder does not exist.'&|
             '||Folder: ' & lFolder & '||The file copy did not occur.', |
             'MFileCopy Error', ICON:Exclamation)
     RETURN(1)
  END

  IF lFlag
     REMOVE(DFile)
  END

  IF EXISTS(gDestFile)
     OPEN(DFile)
     IF ERRORCODE()
        STOP('Destination File Open Error: ' & ERROR())
     END
  ELSE
     CREATE(DFile)
     IF ERRORCODE()
        STOP('Destination File Create Error: ' & ERROR())
     END
     OPEN(DFile)
     IF ERRORCODE()
        STOP('DFile Open Error: ' & ERROR())
     END
  END

  FREE(CFileQ)
  DIRECTORY(CFileQ,lFiles,ff_:Normal)
  IF RECORDS(CFileQ)=0
     RETURN(2)
  END

  SORT(CFileQ,CFQ:ShortName)  ! put the files in file name order

  OPEN(CopyWindow)
  ?ProgressBar{PROP:RangeLow}  = 1
  ?ProgressBar{PROP:RangeHigh} = RECORDS(CFileQ)

  LOOP LP# = 1 TO RECORDS(CFileQ)
    GET(CFileQ,LP#)
    gCFile = CFQ:ShortName
    OPEN(CFile)
    SET(CFile)
    LOOP
      NEXT(CFile)
      IF ERRORCODE()
         CLOSE(CFile)
         IF lEraseFile
            REMOVE(CFile)
         END
         BREAK
      END
      DFL:Chunk = CFL:Chunk
      APPEND(DFile)
      IF ERRORCODE()
         STOP('DFile Append Error: ' & ERROR())
         CLOSE(CFile)
         BREAK
      END
    END
    ?ProgressBar{PROP:Progress} = LP# ; DISPLAY
  END
  CLOSE(DFile)
  CLOSE(CopyWindow)
  RETURN(0)

! Greg Berthume
! www.berthume.com


0
greg3760 (74)
7/16/2003 9:48:34 PM
James Cooke: you'll probably want to add this to the ClarionFoundry.com

"Greg Berthume" <greg@berthume.com> wrote in message
news:3f15c830$1@news.softvelocity.com...
> > COPY('*.std','stdfiles.clm')
> >
> > How can I do something like this in Clarion?  API?
> >
> > Need to copy multiple files into a single file like you can in DOS.
>
> Here's some code I whipped up that does the job if anybody else needs it.
> Make sure you add the DOS driver to your app/project.
>
> ! Procedure Declaration:
>
> MFileCopy               PROCEDURE(STRING pFolder, STRING pFiles, STRING
> pDestFile, BYTE pFlag, BYTE pEraseFile),LONG
>
> ! Globals
>
> gDestFile                 CSTRING(128)
> gCFile                    CSTRING(FILE:MaxFilePath)
>
> ! Usage Example:
>
>   E# = MFileCopy('c:\temp','*.asc','ascfiles.sav',1,1)
>   IF E#
>      STOP('MFileCopy Error: ' & E#)
>   END
>   STOP('MFileCopy Completed')
>
>
>
!---------------------------------------------------------------------------
> -------------------------------!
> MFileCopy PROCEDURE(STRING pFolder, STRING pFiles, STRING pDestFile, BYTE
> pFlag, BYTE pEraseFile)
>
!---------------------------------------------------------------------------
> -------------------------------!
>
> CFile     FILE,DRIVER('DOS'),NAME(gCFile),PRE(CFL),CREATE
> Record    RECORD,PRE()
> Chunk        STRING(128)
>           END
>     END
>
> DFile     FILE,DRIVER('DOS'),NAME(gDestFile),PRE(DFL),CREATE
> Record    RECORD,PRE()
> Chunk        STRING(128)
>           END
>     END
>
> lFolder         CSTRING(FILE:MaxFilePath)
> lFiles          CSTRING(20)
> lFlag           BYTE
> lEraseFile      BYTE
>
> CFileQ          QUEUE(FILE:Queue),PRE(CFQ)
>     END
>
> CopyWindow WINDOW,AT(,,148,45),FONT('Tahoma',10,,),CENTER,GRAY,DOUBLE
>        IMAGE('cmspackage.ico'),AT(6,12),USE(?Image1)
>        STRING('Copying File
> To ->'),AT(29,4),USE(?TransferString),TRN,FONT('Tahoma',10,,FONT:regular)
>        STRING(@s12),AT(92,4),USE(gDestFile)
>        PROGRESS,USE(?ProgressBar),AT(29,16,113,10),RANGE(0,100)
>        STRING('File:'),AT(29,31),USE(?String4)
>        STRING(@s20),AT(46,31,,10),USE(CFQ:ShortName)
>      END
>
>
> CODE
>
>   lFolder   = pFolder
>   lFiles    = pFiles
>   gDestFile = pDestFile
>   lFlag     = pFlag       ! True if the DestFile needs to be deleted if
> exists.
>   lEraseFile= pEraseFile  ! True if erase source file after copying to
> gDestFile?
>
>   SETPATH(lFolder)
>   IF ERRORCODE()
>      BEEP(BEEP:SystemExclamation)  ;  YIELD()
>      MESSAGE('The specified folder does not exist.'&|
>              '||Folder: ' & lFolder & '||The file copy did not occur.', |
>              'MFileCopy Error', ICON:Exclamation)
>      RETURN(1)
>   END
>
>   IF lFlag
>      REMOVE(DFile)
>   END
>
>   IF EXISTS(gDestFile)
>      OPEN(DFile)
>      IF ERRORCODE()
>         STOP('Destination File Open Error: ' & ERROR())
>      END
>   ELSE
>      CREATE(DFile)
>      IF ERRORCODE()
>         STOP('Destination File Create Error: ' & ERROR())
>      END
>      OPEN(DFile)
>      IF ERRORCODE()
>         STOP('DFile Open Error: ' & ERROR())
>      END
>   END
>
>   FREE(CFileQ)
>   DIRECTORY(CFileQ,lFiles,ff_:Normal)
>   IF RECORDS(CFileQ)=0
>      RETURN(2)
>   END
>
>   SORT(CFileQ,CFQ:ShortName)  ! put the files in file name order
>
>   OPEN(CopyWindow)
>   ?ProgressBar{PROP:RangeLow}  = 1
>   ?ProgressBar{PROP:RangeHigh} = RECORDS(CFileQ)
>
>   LOOP LP# = 1 TO RECORDS(CFileQ)
>     GET(CFileQ,LP#)
>     gCFile = CFQ:ShortName
>     OPEN(CFile)
>     SET(CFile)
>     LOOP
>       NEXT(CFile)
>       IF ERRORCODE()
>          CLOSE(CFile)
>          IF lEraseFile
>             REMOVE(CFile)
>          END
>          BREAK
>       END
>       DFL:Chunk = CFL:Chunk
>       APPEND(DFile)
>       IF ERRORCODE()
>          STOP('DFile Append Error: ' & ERROR())
>          CLOSE(CFile)
>          BREAK
>       END
>     END
>     ?ProgressBar{PROP:Progress} = LP# ; DISPLAY
>   END
>   CLOSE(DFile)
>   CLOSE(CopyWindow)
>   RETURN(0)
>
> ! Greg Berthume
> ! www.berthume.com
>
>


0
greg3760 (74)
7/16/2003 9:49:59 PM
Oh yeah, I forgot about your kb Steve!

"Steve Parker" <sparker@NOpar2TREFFAH.com> wrote in message
news:3f15d00d$1@news.softvelocity.com...
> FAQ'd
>
> Steve Parker
>
> --------------------------------------------------
> kb and download center at:
>      www.par2.com
> KB: http://www.par2.com/cws/c5launch.dll/FAQS/THEFAQS.exe.0
> --------------------------------------------------
>
>


0
greg3760 (74)
7/16/2003 10:37:15 PM
Greg -

Maybe SHFileOperation(), but I haven't tried it that way.

On Wed, 16 Jul 2003 13:18:53 -0500, "Greg Berthume"
<greg@berthume.com> wrote:

>
>COPY('*.std','stdfiles.clm')
>
>How can I do something like this in Clarion?  API?
>
>Need to copy multiple files into a single file like you can in DOS.


Jeff Slarve  
http://www.jssoftware.com
0
jslarve (41)
7/16/2003 10:41:42 PM
Maybe.  Not really clear from the MSDN description.

"Jeff Slarve" <jslarve@pe.net> wrote in message
news:l4lbhv4fk4to7v2sr8r2btjlmjdhfq2e9k@4ax.com...
> Greg -
>
> Maybe SHFileOperation(), but I haven't tried it that way.
>
> On Wed, 16 Jul 2003 13:18:53 -0500, "Greg Berthume"
> <greg@berthume.com> wrote:
>
> >
> >COPY('*.std','stdfiles.clm')
> >
> >How can I do something like this in Clarion?  API?
> >
> >Need to copy multiple files into a single file like you can in DOS.
>
>
> Jeff Slarve
> http://www.jssoftware.com


0
greg3760 (74)
7/16/2003 10:45:18 PM
NOTE: In your LOOP to get records...

  APPEND(DFile)  ! not adequate

use

  APPEND(DFile,BYTES(NameOfRecord)) ! for variable length records


You can also increase the size of the DOS record to at least
the size of a small HD cluster, about 2048 or so.

I see more...

Greg Berthume wrote:
> 
> > COPY('*.std','stdfiles.clm')
> >
> > How can I do something like this in Clarion?  API?
> >
> > Need to copy multiple files into a single file like you can in DOS.
> 
> Here's some code I whipped up that does the job if anybody else needs it.
> Make sure you add the DOS driver to your app/project.
> 
> ! Procedure Declaration:
> 
> MFileCopy               PROCEDURE(STRING pFolder, STRING pFiles, STRING
> pDestFile, BYTE pFlag, BYTE pEraseFile),LONG
> 
> ! Globals
> 
> gDestFile                 CSTRING(128)
> gCFile                    CSTRING(FILE:MaxFilePath)
> 
> ! Usage Example:
> 
>   E# = MFileCopy('c:\temp','*.asc','ascfiles.sav',1,1)
>   IF E#
>      STOP('MFileCopy Error: ' & E#)
>   END
>   STOP('MFileCopy Completed')
> 
> !---------------------------------------------------------------------------
> -------------------------------!
> MFileCopy PROCEDURE(STRING pFolder, STRING pFiles, STRING pDestFile, BYTE
> pFlag, BYTE pEraseFile)
> !---------------------------------------------------------------------------
> -------------------------------!
> 
> CFile     FILE,DRIVER('DOS'),NAME(gCFile),PRE(CFL),CREATE
> Record    RECORD,PRE()
> Chunk        STRING(128)
>           END
>     END
> 
> DFile     FILE,DRIVER('DOS'),NAME(gDestFile),PRE(DFL),CREATE
> Record    RECORD,PRE()
> Chunk        STRING(128)
>           END
>     END
> 
> lFolder         CSTRING(FILE:MaxFilePath)
> lFiles          CSTRING(20)
> lFlag           BYTE
> lEraseFile      BYTE
> 
> CFileQ          QUEUE(FILE:Queue),PRE(CFQ)
>     END
> 
> CopyWindow WINDOW,AT(,,148,45),FONT('Tahoma',10,,),CENTER,GRAY,DOUBLE
>        IMAGE('cmspackage.ico'),AT(6,12),USE(?Image1)
>        STRING('Copying File
> To ->'),AT(29,4),USE(?TransferString),TRN,FONT('Tahoma',10,,FONT:regular)
>        STRING(@s12),AT(92,4),USE(gDestFile)
>        PROGRESS,USE(?ProgressBar),AT(29,16,113,10),RANGE(0,100)
>        STRING('File:'),AT(29,31),USE(?String4)
>        STRING(@s20),AT(46,31,,10),USE(CFQ:ShortName)
>      END
> 
> CODE
> 
>   lFolder   = pFolder
>   lFiles    = pFiles
>   gDestFile = pDestFile
>   lFlag     = pFlag       ! True if the DestFile needs to be deleted if
> exists.
>   lEraseFile= pEraseFile  ! True if erase source file after copying to
> gDestFile?
> 
>   SETPATH(lFolder)
>   IF ERRORCODE()
>      BEEP(BEEP:SystemExclamation)  ;  YIELD()
>      MESSAGE('The specified folder does not exist.'&|
>              '||Folder: ' & lFolder & '||The file copy did not occur.', |
>              'MFileCopy Error', ICON:Exclamation)
>      RETURN(1)
>   END
> 
>   IF lFlag
>      REMOVE(DFile)
>   END
> 
>   IF EXISTS(gDestFile)
>      OPEN(DFile)
>      IF ERRORCODE()
>         STOP('Destination File Open Error: ' & ERROR())
>      END
>   ELSE
>      CREATE(DFile)
>      IF ERRORCODE()
>         STOP('Destination File Create Error: ' & ERROR())
>      END
>      OPEN(DFile)
>      IF ERRORCODE()
>         STOP('DFile Open Error: ' & ERROR())
>      END
>   END
> 
>   FREE(CFileQ)
>   DIRECTORY(CFileQ,lFiles,ff_:Normal)
>   IF RECORDS(CFileQ)=0
>      RETURN(2)
>   END
> 
>   SORT(CFileQ,CFQ:ShortName)  ! put the files in file name order
> 
>   OPEN(CopyWindow)
>   ?ProgressBar{PROP:RangeLow}  = 1
>   ?ProgressBar{PROP:RangeHigh} = RECORDS(CFileQ)
> 
>   LOOP LP# = 1 TO RECORDS(CFileQ)
>     GET(CFileQ,LP#)
>     gCFile = CFQ:ShortName
>     OPEN(CFile)
>     SET(CFile)
>     LOOP
>       NEXT(CFile)
>       IF ERRORCODE()
>          CLOSE(CFile)
>          IF lEraseFile
>             REMOVE(CFile)
>          END
>          BREAK
>       END
>       DFL:Chunk = CFL:Chunk
>       APPEND(DFile)
>       IF ERRORCODE()
>          STOP('DFile Append Error: ' & ERROR())
>          CLOSE(CFile)
>          BREAK
>       END
>     END
>     ?ProgressBar{PROP:Progress} = LP# ; DISPLAY
>   END
>   CLOSE(DFile)
>   CLOSE(CopyWindow)
>   RETURN(0)
> 
> ! Greg Berthume
> ! www.berthume.com

-- 
 Randy Goodhew 
 ---[ eQ ]---
0
rgoodhew (58)
7/17/2003 12:32:18 AM
>   APPEND(DFile,BYTES(NameOfRecord)) ! for variable length records

This results in a "No Matching Prototype" compile error.

I tried both DFL:Chunk and DFL:Record

Greg


0
greg3760 (74)
7/17/2003 2:35:32 PM
Looks like SIZE() is needed and not BYTES().

"Randy Goodhew" <rgoodhew@fuse.net> wrote in message
news:3F15EE92.F600BB73@fuse.net...
> NOTE: In your LOOP to get records...
>
>   APPEND(DFile)  ! not adequate
>
> use
>
>   APPEND(DFile,BYTES(NameOfRecord)) ! for variable length records
>
>
> You can also increase the size of the DOS record to at least
> the size of a small HD cluster, about 2048 or so.
>
> I see more...
>
> Greg Berthume wrote:
> >
> > > COPY('*.std','stdfiles.clm')
> > >
> > > How can I do something like this in Clarion?  API?
> > >
> > > Need to copy multiple files into a single file like you can in DOS.
> >
> > Here's some code I whipped up that does the job if anybody else needs
it.
> > Make sure you add the DOS driver to your app/project.
> >
> > ! Procedure Declaration:
> >
> > MFileCopy               PROCEDURE(STRING pFolder, STRING pFiles, STRING
> > pDestFile, BYTE pFlag, BYTE pEraseFile),LONG
> >
> > ! Globals
> >
> > gDestFile                 CSTRING(128)
> > gCFile                    CSTRING(FILE:MaxFilePath)
> >
> > ! Usage Example:
> >
> >   E# = MFileCopy('c:\temp','*.asc','ascfiles.sav',1,1)
> >   IF E#
> >      STOP('MFileCopy Error: ' & E#)
> >   END
> >   STOP('MFileCopy Completed')
> >
> >
!---------------------------------------------------------------------------
> > -------------------------------!
> > MFileCopy PROCEDURE(STRING pFolder, STRING pFiles, STRING pDestFile,
BYTE
> > pFlag, BYTE pEraseFile)
> >
!---------------------------------------------------------------------------
> > -------------------------------!
> >
> > CFile     FILE,DRIVER('DOS'),NAME(gCFile),PRE(CFL),CREATE
> > Record    RECORD,PRE()
> > Chunk        STRING(128)
> >           END
> >     END
> >
> > DFile     FILE,DRIVER('DOS'),NAME(gDestFile),PRE(DFL),CREATE
> > Record    RECORD,PRE()
> > Chunk        STRING(128)
> >           END
> >     END
> >
> > lFolder         CSTRING(FILE:MaxFilePath)
> > lFiles          CSTRING(20)
> > lFlag           BYTE
> > lEraseFile      BYTE
> >
> > CFileQ          QUEUE(FILE:Queue),PRE(CFQ)
> >     END
> >
> > CopyWindow WINDOW,AT(,,148,45),FONT('Tahoma',10,,),CENTER,GRAY,DOUBLE
> >        IMAGE('cmspackage.ico'),AT(6,12),USE(?Image1)
> >        STRING('Copying File
> >
To ->'),AT(29,4),USE(?TransferString),TRN,FONT('Tahoma',10,,FONT:regular)
> >        STRING(@s12),AT(92,4),USE(gDestFile)
> >        PROGRESS,USE(?ProgressBar),AT(29,16,113,10),RANGE(0,100)
> >        STRING('File:'),AT(29,31),USE(?String4)
> >        STRING(@s20),AT(46,31,,10),USE(CFQ:ShortName)
> >      END
> >
> > CODE
> >
> >   lFolder   = pFolder
> >   lFiles    = pFiles
> >   gDestFile = pDestFile
> >   lFlag     = pFlag       ! True if the DestFile needs to be deleted if
> > exists.
> >   lEraseFile= pEraseFile  ! True if erase source file after copying to
> > gDestFile?
> >
> >   SETPATH(lFolder)
> >   IF ERRORCODE()
> >      BEEP(BEEP:SystemExclamation)  ;  YIELD()
> >      MESSAGE('The specified folder does not exist.'&|
> >              '||Folder: ' & lFolder & '||The file copy did not occur.',
|
> >              'MFileCopy Error', ICON:Exclamation)
> >      RETURN(1)
> >   END
> >
> >   IF lFlag
> >      REMOVE(DFile)
> >   END
> >
> >   IF EXISTS(gDestFile)
> >      OPEN(DFile)
> >      IF ERRORCODE()
> >         STOP('Destination File Open Error: ' & ERROR())
> >      END
> >   ELSE
> >      CREATE(DFile)
> >      IF ERRORCODE()
> >         STOP('Destination File Create Error: ' & ERROR())
> >      END
> >      OPEN(DFile)
> >      IF ERRORCODE()
> >         STOP('DFile Open Error: ' & ERROR())
> >      END
> >   END
> >
> >   FREE(CFileQ)
> >   DIRECTORY(CFileQ,lFiles,ff_:Normal)
> >   IF RECORDS(CFileQ)=0
> >      RETURN(2)
> >   END
> >
> >   SORT(CFileQ,CFQ:ShortName)  ! put the files in file name order
> >
> >   OPEN(CopyWindow)
> >   ?ProgressBar{PROP:RangeLow}  = 1
> >   ?ProgressBar{PROP:RangeHigh} = RECORDS(CFileQ)
> >
> >   LOOP LP# = 1 TO RECORDS(CFileQ)
> >     GET(CFileQ,LP#)
> >     gCFile = CFQ:ShortName
> >     OPEN(CFile)
> >     SET(CFile)
> >     LOOP
> >       NEXT(CFile)
> >       IF ERRORCODE()
> >          CLOSE(CFile)
> >          IF lEraseFile
> >             REMOVE(CFile)
> >          END
> >          BREAK
> >       END
> >       DFL:Chunk = CFL:Chunk
> >       APPEND(DFile)
> >       IF ERRORCODE()
> >          STOP('DFile Append Error: ' & ERROR())
> >          CLOSE(CFile)
> >          BREAK
> >       END
> >     END
> >     ?ProgressBar{PROP:Progress} = LP# ; DISPLAY
> >   END
> >   CLOSE(DFile)
> >   CLOSE(CopyWindow)
> >   RETURN(0)
> >
> > ! Greg Berthume
> > ! www.berthume.com
>
> -- 
>  Randy Goodhew
>  ---[ eQ ]---


0
greg3760 (74)
7/17/2003 2:39:06 PM
Greg Berthume wrote:
<snip> 
> Looks like SIZE() is needed and not BYTES().

No. SIZE will not adjust for variable length records.

> > NOTE: In your LOOP to get records...
> >
> >   APPEND(DFile)  ! not adequate
> >
> > use
> >
> >   APPEND(DFile,BYTES(NameOfRecord)) ! for variable length records
> >

My mistake: :(

Use:
   APPEND(DFile,BYTES(filename)) ! for variable length records  

See HELP:
-----------------
BYTES(file)

BYTES	Returns number of bytes in FILE, or most recently read.

file	The label of a FILE.

The BYTES procedure returns the size of a FILE in bytes or the number of
bytes in the last record successfully accessed. Following an OPEN
statement, BYTES returns the size of the file. After the file has been
successfully accessed by GET, REGET, NEXT, PREVIOUS, ADD, or PUT, the
BYTES procedure returns the number of bytes accessed in the RECORD. The
BYTES procedure may be used to return the number of bytes read in a
variable length record.

Return Data Type:  	LONG

Example:

DosFileName		STRING(260),STATIC

LastRec 				LONG
SavPtr 				LONG(1)														!Start at 1
FileSize			LONG
DosFile				FILE,DRIVER('DOS'),PRE(DOS),NAME(DosFileName)
Record					RECORD
F1								STRING(2000)
							. .
BlobStorage		FILE,DRIVER('TopSpeed'),PRE(STO)
File						BLOB,BINARY	 						
Record					RECORD
FileName					STRING(64)
							. .
	CODE
	IF NOT FILEDIALOG('Choose File to Store',DosFileName,,0010b) THEN
RETURN.
	OPEN(BlobStorage)															!Open the BLOB file

STO:FileName = DosFileName											! and store the filename
	OPEN(DosFile)																	!Open the file
	FileSize = BYTES(DosFile) 											!Get size of file
	STO:File{PROP:Size} = FileSize									! and set the BLOB to store the
file
	LastRec = FileSize % SIZE(DOS:Record)					!Check for short record at
end of file
	LOOP INT(FileSize/SIZE(DOS:Record)) TIMES
		GET(DosFile,SavPtr)													!Get each record
		ASSERT(NOT ERRORCODE())

STO:File[SavPtr - 1 : SavPtr + SIZE(DOS:Record) - 2] = DOS:Record
																								!String slice data into BLOB
		SavPtr += SIZE(DOS:Record)										!Compute next record pointer
	END
	IF LastRec																			!If short record at end of file
		GET(DosFile,SavPtr)													!Get last record
		ASSERT(BYTES(DosFile) = LastRec)							! size read should match
computed size
		STO:File[SavPtr - 1 : SavPtr + LastRec - 2] = DOS:Record

END
	ADD(BlobStorage)
	ASSERT(NOT ERRORCODE())
	CLOSE(DosFile);CLOSE(BlobStorage)



-- 
 Randy Goodhew 
 ---[ eQ ]---
0
rgoodhew (58)
7/17/2003 4:59:27 PM
If I use BYTES(File), the size of the destination file is a bit smaller than
the sum of the copied files.

If I use SIZE(record) in the append(), the sum is equal to the sum of the
copied file sizes.

Why is this?

"Randy Goodhew" <rgoodhew@fuse.net> wrote in message
news:3F16D5EF.33276480@fuse.net...
> Greg Berthume wrote:
> <snip>
> > Looks like SIZE() is needed and not BYTES().
>
> No. SIZE will not adjust for variable length records.
>
> > > NOTE: In your LOOP to get records...
> > >
> > >   APPEND(DFile)  ! not adequate
> > >
> > > use
> > >
> > >   APPEND(DFile,BYTES(NameOfRecord)) ! for variable length records
> > >
>
> My mistake: :(
>
> Use:
>    APPEND(DFile,BYTES(filename)) ! for variable length records
>
> See HELP:
> -----------------
> BYTES(file)
>
> BYTES Returns number of bytes in FILE, or most recently read.
>
> file The label of a FILE.
>
> The BYTES procedure returns the size of a FILE in bytes or the number of
> bytes in the last record successfully accessed. Following an OPEN
> statement, BYTES returns the size of the file. After the file has been
> successfully accessed by GET, REGET, NEXT, PREVIOUS, ADD, or PUT, the
> BYTES procedure returns the number of bytes accessed in the RECORD. The
> BYTES procedure may be used to return the number of bytes read in a
> variable length record.
>
> Return Data Type:  LONG
>
> Example:
>
> DosFileName STRING(260),STATIC
>
> LastRec LONG
> SavPtr LONG(1) !Start at 1
> FileSize LONG
> DosFile FILE,DRIVER('DOS'),PRE(DOS),NAME(DosFileName)
> Record RECORD
> F1 STRING(2000)
> . .
> BlobStorage FILE,DRIVER('TopSpeed'),PRE(STO)
> File BLOB,BINARY
> Record RECORD
> FileName STRING(64)
> . .
> CODE
> IF NOT FILEDIALOG('Choose File to Store',DosFileName,,0010b) THEN
> RETURN.
> OPEN(BlobStorage) !Open the BLOB file
>
> STO:FileName = DosFileName ! and store the filename
> OPEN(DosFile) !Open the file
> FileSize = BYTES(DosFile) !Get size of file
> STO:File{PROP:Size} = FileSize ! and set the BLOB to store the
> file
> LastRec = FileSize % SIZE(DOS:Record) !Check for short record at
> end of file
> LOOP INT(FileSize/SIZE(DOS:Record)) TIMES
> GET(DosFile,SavPtr) !Get each record
> ASSERT(NOT ERRORCODE())
>
> STO:File[SavPtr - 1 : SavPtr + SIZE(DOS:Record) - 2] = DOS:Record
> !String slice data into BLOB
> SavPtr += SIZE(DOS:Record) !Compute next record pointer
> END
> IF LastRec !If short record at end of file
> GET(DosFile,SavPtr) !Get last record
> ASSERT(BYTES(DosFile) = LastRec) ! size read should match
> computed size
> STO:File[SavPtr - 1 : SavPtr + LastRec - 2] = DOS:Record
>
> END
> ADD(BlobStorage)
> ASSERT(NOT ERRORCODE())
> CLOSE(DosFile);CLOSE(BlobStorage)
>
>
>
> -- 
>  Randy Goodhew
>  ---[ eQ ]---


0
greg3760 (74)
7/17/2003 5:17:19 PM

Greg Berthume wrote:
> 
> If I use BYTES(File), the size of the destination file is a bit smaller than
> the sum of the copied files.
> 
> If I use SIZE(record) in the append(), the sum is equal to the sum of the
> copied file sizes.
> 
> Why is this?

Your Record size is 128 bytes. If the size of the files you are 
reading/writing are not exactly divisable by 128, then the short
record will be accounted for if you use BYTES(). Otherwise, all
reads/writes will be exactly 128 bytes (or whatever size the buffer
you are using).

I tried BYTES() with two files, one was 38 bytes in size and
the other was 1721 bytes. The combined file was 1759 bytes.
Without the BYTES() adjust, the combined file was 1920 bytes
(128 x 15).

NOTE: If you concatenate text files with the DOS command COPY,
e.g.  COPY A.TXT+B.TXT+C.TXT NEWFILE.TXT,
it will add a Ctrl-Z or '<26>' to the end of NEWFILE.TXT.


-- 
 Randy Goodhew 
 ---[ eQ ]---

0
rgoodhew (58)
7/18/2003 1:13:12 PM
Makes sense.  I did increase the record size.  The copy happens very fast.

Thanks.

Greg Berthume
Berthume Software
www.berthume.com
greg@berthume.com

"Randy Goodhew" <rgoodhew@fuse.net> wrote in message
news:3F17F268.122275B5@fuse.net...
>
>
> Greg Berthume wrote:
> >
> > If I use BYTES(File), the size of the destination file is a bit smaller
than
> > the sum of the copied files.
> >
> > If I use SIZE(record) in the append(), the sum is equal to the sum of
the
> > copied file sizes.
> >
> > Why is this?
>
> Your Record size is 128 bytes. If the size of the files you are
> reading/writing are not exactly divisable by 128, then the short
> record will be accounted for if you use BYTES(). Otherwise, all
> reads/writes will be exactly 128 bytes (or whatever size the buffer
> you are using).
>
> I tried BYTES() with two files, one was 38 bytes in size and
> the other was 1721 bytes. The combined file was 1759 bytes.
> Without the BYTES() adjust, the combined file was 1920 bytes
> (128 x 15).
>
> NOTE: If you concatenate text files with the DOS command COPY,
> e.g.  COPY A.TXT+B.TXT+C.TXT NEWFILE.TXT,
> it will add a Ctrl-Z or '<26>' to the end of NEWFILE.TXT.
>
>
> -- 
>  Randy Goodhew
>  ---[ eQ ]---
>


0
greg3760 (74)
7/18/2003 3:41:08 PM
to continue...

What do you do if the a file or a set of files doesn't complete
the copy/append process?

Think about exception handling...

Greg Berthume wrote:
> 
> Makes sense.  I did increase the record size.  The copy happens very fast.
> 
> Thanks.
> 
> Greg Berthume

-- 
 Randy Goodhew 
 ---[ eQ ]---
0
rgoodhew (58)
7/18/2003 7:37:14 PM
Reply: