Operations with Files and Directories
FILE-COPY: "from_filename" "to_filename"
This word copies a specified file. If the target directory already contains
the file with specified name, the old file will be overwritten (unless it is
used by another application ). If you don't change the filename when copying
a file, then it would be sufficient to specify the receiving directory (without
filename) in the argument to_filename.
This command does not support operations with file masks and it cannot be used
to delete a directory. To process several files, use FOR-FILES:
loop.
Examples:
FILE-COPY: "c:\xxx\test.txt" "c:\xxx\new.txt" FILE-COPY: "c:\xxx\test.txt" "d:\backup\another_test.txt" \ copying file test.txt to directory c:\yyy\ FILE-COPY: "c:\xxx\test.txt" "c:\yyy\" \ copying file test.txt to file backup FILE-COPY: "c:\xxx\test.txt" "c:\backup"
If an error occurs during execution of this command, you can find out the error number by using GetLastError word.
There also exists a postfix version of this word:
S" from_filename" S" to_filename" FCOPY
FILE-MOVE: "from_filename" "to_filename"
This word moves a specified file. If you don't change the filename when moving
a file, then it would be sufficient to specify the receiving directory (without
filename) in the argument to_filename.
This command does not support operations with file masks and it cannot be used
to delete a directory. To process several files, use FOR-FILES:
loop.
Examples:
FILE-MOVE: "c:\xxx\test.txt" "c:\xxx\new.txt" FILE-MOVE: "c:\xxx\test.txt" "d:\backup\test.txt" \ moving file test.txt to directory c:\yyy\ FILE-MOVE: "c:\xxx\test.txt" "c:\yyy\" \ moving file test.txt to file backup FILE-MOVE: "c:\xxx\test.txt" "c:\backup"
If an error occurs during execution of this command, you can find out the error number by using GetLastError word.
There also exists a postfix version of this word:
S" from_filename" S" to_filename" FMOVE
FILE-RENAME: "old_filename" "new_filename"
Renames a specified file. If you use this word just to move a file without changing its filename, then it would be sufficient to specify the receiving directory (without filename) in the argument to_filename. Unlike "FILE-MOVE:" word, this command can rename (move) directories, but only within the same drive.
Examples:
FILE-RENAME: "c:\xxx\test.txt" "c:\xxx\new.txt" FILE-RENAME: "c:\xxx" "c:\yyy" \ only within the same drive \ moving file test.txt to directory c:\yyy\ FILE-RENAME: "c:\xxx\test.txt" "c:\yyy\" \ renaming file test.txt to backup FILE-RENAME: "c:\xxx\test.txt" "c:\backup"
If an error occurs during execution of this command, you can find out the error number by using GetLastError word.
There also exists a postfix version of this word:
S" old_filename" S" new_filename" FRENAME
Returns the size of a specified file (double number). To get the aggregate size of all files in a directory use the word DIR-SIZE:.
Examples:
\ checking file size and displaying a message 10240. FILE-SIZE: "c:\test.txt" D< IF MSG: "File size exceeds 10kb" ELSE MSG: "File size less then 10kb" THEN
#( test_file_size \ the action will be executed if the file size exceeds 10 kb Rule: 10240. FILE-SIZE: "c:\test.txt" D< Action: \ ... performing some useful actions )# #( test_file_size1 \ displaying a message if a specified file \ is greater than 100kb NoActive Action: 102400. FILE-SIZE: "c:\fido\sessions.log" D< IF MSG: "File size exceeds 100 kb!" THEN )# #( test_delete_empty \ recursively deleting from a specified folder \ all the files whose size equals 0 NoActive Action: RECURSIVE FOR-FILES: "c:\xxx\*.*" 0. FILE-SIZE: "%FOUND-FULLPATH%" D= IF FILE-DELETE: "%FOUND-FULLPATH%" THEN ;FOR-FILES )#
There also exists a postfix version of this word:
S" filename" FSIZE
Deletes a specified file. Supports masks of filenames. If you want to delete all files matching a specified mask not just in main directory, but in all its subdirectories as well, use modifier RECURSIVE before word FILE-DELETE:
This word cannot be used to delete a directory. If you want to delete a directory rather then a file, use DIR-DELETE.
Example:
FILE-DELETE: "c:\xxx\test.txt"
FILE-DELETE: "c:\xxx\*.txt"
RECURSIVE FILE-DELETE: "c:\xxx\*.txt"
If an error occurs during execution of this command, you can find out the error number by using GetLastError word.
There also exists a postfix version of this word:
S" filename" FDELETE
You shouldn't use with this word the standard method of getting an error code (GetLastError), because FILE-DELETE: works with masks and always returns error #18 (There are no more files. ERROR_NO_MORE_FILES).
However, if you want to get an error code after deleting a file, you can use a standard Forth word DELETE-FILE ( c-addr u -- ior )
Example:
S" myfile.txt" DELETE-FILE ?DUP IF ." Error # " . CR THEN
Returns TRUE (-1) if a file is empty or if it doesn't exist.
Returns TRUE (-1) if a specified file or directory exists.
There also exists a postfix version of this word:
S" file_pattern" EXIST?
Creates an empty new file with a specified name. Creates all the intermediate directories if necessary. If you want to create a directory rather then a file, use DIR-CREATE:.
Examples:
\ creates an empty file named 'test.txt' in the root directory of C: drive FILE-CREATE: "c:\test.txt" \ creates an empty file named 'test.txt' in 'c:\xxx\yyy\zzz' \ all the intermediate directories which do not exist will be created. FILE-CREATE: "c:\xxx\yyy\zzz\test.txt"
If an error occurs during execution of this command, you can find out the error number by using GetLastError word.
There also exists a postfix version of this word:
S" filename" FCREATE
Writes content of argument "text" into a specified file, removing the file's previous content.
It is possible to use user-defined variables and nnCron's predefined variables in arguments of word FILE-WRITE. To write into a file quotation mark character and per cent sign character, use variables %QUOTE% and %PERCENT% respectively. You can use variable %FILE: filename% to write to a file content of another file.
Examples:
FILE-WRITE: "c:\xxx\test.txt" "Last update: %hh%:%mm%" FILE-WRITE: "c:\xxx\test.txt" "%USERNAME% was there!" FILE-WRITE: "c:\xxx\test.txt" "Content of another file:%crlf%%crlf%%FILE: c:\yyy\source.txt%"
If an error occurs during execution of this command, you can find out the error number by using GetLastError word.
There also exists a postfix version of this word:
S" filename" S" text" FWRITE
FILE-APPEND: "filename" "text"
This word is similar to FILE-WRITE:, but it does not overwrite the target file's content, but appends the new information in the end of file.
Examples:
FILE-APPEND: "c:\xxx\test.txt" "Message was sent at: %hh%:%mm%%crlf%" FILE-APPEND: "c:\xxx\test.txt" "Content of another file:%crlf%%FILE: c:\yyy\source.txt%"
If an error occurs during execution of this command, you can find out the error number by using GetLastError word.
There also exists a postfix version of this word (FAPPEND):
S" text" S" filename" FAPPEND
Creates a specified directory and, if necessary, all the intermediate directories.
If an error occurs during execution of this command, you can find out the error number by using GetLastError word.
Deletes a specified directory or a directory tree.
Use with care: a specified catalog or a tree will be deleted even if they are
not empty.
Example:
DIR-DELETE: "c:\xxx"
If an error occurs during execution of this command, you can find out the error number by using GetLastError word.
Returns the aggregate size of all files in a directory (a double number).
Example:
#( test_dir_size \ displaying a message if aggregate size of files \ in directory c:\cpp exceeds 100kb (without subdirectories) NoActive Action: 102400. DIR-SIZE: "c:\cpp" D< IF MSG: "Dir size exceeds 100 kb!" THEN )#
In order to find out a size of a directory including all the subdirectories, place modifier RECURSIVE before DIR-SIZE:.
Example:
#( test_dir_size1 \ displaying a message if aggregate size in directory 'c:\cpp' \ exceeds 100kb (including files in all subdirectories) NoActive Action: 102400. RECURSIVE DIR-SIZE: "c:\cpp" D< IF MSG: "Dir size exceeds 100 kb!" THEN )#
There also exists a postfix version of this word:
S" dirname" DIR-SIZE
Returns "TRUE" if a specified directory is empty and "FALSE"
if it contains at least on file or subdirectory.
Please note that DIR-EMPTY returns "TRUE" even if a specified
directory does not exist.
Receives a string with full file path and file name (S" fullpath" ONLYDIR) and returns a string, containing file path only (without a file name). For example, when receiving a string 'd:\tools\nnbackup\nnbackup.exe', this word will return 'd:\tools\nnbackup'.
Attention please: you can use this word when defining a task, but you can not use it in console!
Example:
#( test_filename NoActive Action: FILESONLY FOR-FILES: "C:\TEMP\*" MSG: "Full filename: %FOUND-FULLPATH%%crlf%\ Path only: %FOUND-FULLPATH ONLYDIR%"
;FOR-FILES )#
See also: ONLYNAME
Receives a string with full file path and file name (S" fullpath" ONLYNAME) and returns a string, containing file name only (without a file path). For example, when receiving a string 'd:\tools\nnbackup\nnbackup.exe', this word will return 'nnbackup.exe'.
Attention please: you can use this word when defining a task, but you can not use it in console!
Example:
#( test_filename1 NoActive Action: FILESONLY FOR-FILES: "C:\TEMP\*" MSG: "Full filename: %FOUND-FULLPATH%%crlf%\ Name only: %FOUND-FULLPATH ONLYNAME%"
;FOR-FILES )#
See also: ONLYDIR
FOR-FILES: "path\mask" <...> ;FOR-FILES
This word can be used to perform operations not just on single files, but entire groups of files matching a specified filename mask; commands included in the body of FOR-FILES loop will be applied to each of these files.
Example:
#( test_for_files \ removing all the files with "*.txt" extension in directory "c:\xxx" NoActive Action: FOR-FILES: "c:\xxx\*.txt" FILE-DELETE: "%FOUND-FULLPATH%" ;FOR-FILES )#
It works in this way: if there are five files matching a certain mask, then FOR-FILES: loop will be automatically executed five times and each time values of the following variables will be renewed:
%FOUND-FILENAME% | name of a file matching the search pattern (e.g. test.txt) |
%FOUND-FULLPATH% | full path and name of file matching the search pattern (e.g. 'c:\xxx\yyy\test.txt') |
%FOUND-RELPATH% | path and name of file matching the search pattern, relative to the directory where search is performed (e.g. 'yyy\test.txt') |
That means that on each iteration of the loop you get access to the name of the next file matching a specified mask, and now it only remains to perform the required action with this file (i.e. remove, move or rename it etc.) or to perform another check in order to decide what to do with this particular file.
Here is the list of checks which can be performed in the body of FOR-FILES: loop (use word "0=", to reverse the condition):
IS-DIR? | Returns 'TRUE' if a directory is found |
IS-HIDDEN? | Returns 'TRUE' if a file/directory with attribute hidden is found |
IS-READONLY? | Returns 'TRUE' if a file/directory with attribute read-only is found' |
IS-SYSTEM? |
Returns 'TRUE' if a file/directory with attribute system is found |
IS-ARCHIVE? | Returns 'TRUE' if a file/directory with attribute hidden is found' |
Example:
\ all the file and subdirectories inside the directory "c:\xxx" match the pattern used here, \ but due to additional checks, we will only process subdirectories \ and files with attributes "hidden" and "read-only" FOR-FILES: "c:\xxx\*" \ checking if the found file is a directory IS-DIR? IF \ ... commands for performing operations with directories, including those with "hidden" and "read-only" attributes ELSE
\ checking if the found file has attribute "hidden" IS-HIDDEN? IF \ ... commands for performing operations with hidden files ELSE \ checking if the found file has attribute "read-only" IS-READONLY? IF \ ... commands for performing operations with read-only files THEN THEN THEN ;FOR-FILES
Besides, the body of FOR-FILES: loop can contain instructions for performing operations with dates of file creation and modification and last access (take a look at "Working with Dates and Time"):
CREATION-DATE | Date of creation of a found file |
ACCESS-DATE | Date of last access to found file |
WRITE-DATE | Date when a found file was written |
CUR-DATE | System date |
DATE- | Difference between two dates ( date1-date2 ). Returns the difference between two dates in days. |
Example:
#( test_for_files1 \ removes from directory "c:\xxx" all files \ created more than ten days ago NoActive Action: FOR-FILES: "c:\xxx\*" \ working only with files, ruling directories out IS-DIR? 0=
IF CUR-DATE CREATION-DATE DATE- 10 > IF FILE-DELETE: "%FOUND-FULLPATH%" THEN THEN ;FOR-FILES )#
The following modifiers can be used before FOR-FILES:
RECURSIVE |
Working with a specified directory and all its subdirectories |
TODEPTH | Searching the "deep levels" of a directory tree.
There are two ways to perform a search in a directory tree: |
FILESONLY |
Instructions in the body of FOR-FILES: are performed on files only, and not on directories. |
SKIPERRORS |
Ignore file access errors when moving through a directory tree |
Examples:
#( test_for_files2 \ removing all the files and directories in directory "c:\xxx". \ word FILE-DELETE: deletes files, \ and word DIR-DELETE: deletes directories NoActive Action: RECURSIVE FOR-FILES: "c:\xxx\*" \ checking if the found file is a directory IS-DIR? IF DIR-DELETE: "%FOUND-FULLPATH%" ELSE FILE-DELETE: "%FOUND-FULLPATH%" THEN ;FOR-FILES )#
#( test_for_files3 \ deleting all files with zero length from directory c:\zzz and all its subdirectories \ deleting files only, but not the directories. NoActive Action: RECURSIVE FILESONLY FOR-FILES: "c:\zzz\*.*" FILE-SIZE: "%FOUND-FULLPATH%" D0= IF FILE-DELETE: "%FOUND-FULLPATH%" THEN ;FOR-FILES )#
If necessary, you can always exit FOR-FILES: loop by using word FF-EXIT.
Example:
#( test_for_files4 \ displays messages with names of all \ text files in directory C:\TEMP\ \ exits the loop when file exit.txt is found NoActive Action: FOR-FILES: "C:\TEMP\*.txt" MSG: "%FOUND-FILENAME%" \ matching name of each found file against name "exit.txt" RE-MATCH: "%FOUND-FILENAME%" "/exit.txt/i" \ if name is the same, leaving the loop IF FF-EXIT THEN ;FOR-FILES BEEP: 250 500 )#
FILE-CROP: "filename" <max_size> <size_after_crop>
Permits to control size of text files. Removes beginning of a specified file so that its size does not exceed the value of size_after_crop. File will be cropped only if its size is greater than the value of max_size.
Values of max_size è size_after_crop are in kilobytes.
This word is used mostly to control size of log files.
Example:
\ log file sessions.log will be cropped down to 500 kb \ if it was greater than 1000 kb when FILE-CROP was called FILE-CROP: "c:\fido\sessions.log" 1000 500 \ log file nncron.log will be cropped down to 50 kb \ if it was greater than 100 kb when FILE-CROP was called FILE-CROP: "log\nncron.log" 100 50
There also exists a postfix version of this word:
S" filename" <max_size> <size_after_crop> FCROPkb
PURGE-OLD: "path\mask" <days>
PURGE-OLDW: "path\mask" <days>
PURGE-OLDA: "path\mask" <days>
These words remove all the files which match a specified mask and are older then a specified number of days. PURGE-OLD: checks the file creation date, PURGE-OLDW: checks the date when a file was last written into and PURGE-OLDA: checks the date when a file was last accessed.
Use modifier RECURSIVE to delete all files in the specified directory and all its subdirectories.
If value of days is set to -1, then all files will be deleted from a directory.
Examples:
\ deleting all files more than 3 days old from Windows Temp directory PURGE-OLD: "c:\windows\temp\*" 3 \ deleting from the specified directory and all its subdirectories all text files
\ which were last written into more that 10 days ago RECURSIVE
PURGE-OLDW: "c:\drafts\*.txt" 10
\ removing all files from Windows Temp directory
PURGE-OLD: "c:\windows\temp\*" -1
By default, words of PURGE-OLD*: group remove only files, but by using modifier WITHDIRS, you can delete both files an directories older than a specified number of days. Please be careful when using it: directories older than a specified period of time will be deleted with all their content!
Example:
\ removing ALL files and directories WITHDIRS PURGE-OLD: "c:\windows\temp\*" -1
There also exists a postfix version of these words:
S" c:\temp\*.txt" -1 PURGE-OLD S" c:\temp\*" 10 PURGE-OLDW WITHDIRS S" c:\temp\test\*.bat" 5 PURGE-OLDA
FILE-CREATION-DATE: "path" (you can also use word FILE-DATE: "path")
FILE-ACCESS-DATE: "path"
FILE-WRITE-DATE: "path"
These words return numeric values of date of creation of a file, date of last access and date when the file was last modified (these values are resented in a special binary DATE-format). These three words can be used to perform operations with these three types of dates.
Current system time can be placed on stack with the help of word CUR-DATE. Word DATE- returns the difference (in days) between 2 dates. Methods of handling dates and of their conversion between different formats are described in chapter Working with Dates and Time.
Examples:
#( test_file_date \ removing file new.txt if it was created more than 30 days ago NoActive Action: CUR-DATE FILE-CREATION-DATE: "c:\xxx\new.txt" DATE- 30 > IF FILE-DELETE: "c:\xxx\new.txt" THEN )#
There also exists a postfix version of these words:
S" filename" FCDATE S" filename" FADATE S" filename" FWDATE
See also: