Skip to content
QiTASC.com / intaQt Built-ins /
File Built-ins
/ .. /
File Built-ins





File Built-ins

File Built-ins provide methods for file system access. A list of compatible charsets is available via Github - Class Charsets.

File From Project

This function returns the file from the current execution context's project folder.

Syntax

1
<file File> := File.fromProject(<path String>)

Returns
The specified file.

Parameter

  • path - The relative path to the project root folder

Example

1
2
3
stepdef "assert file {} exists in Project" / fileName /
    assert File.fromProject("../TestProject01/" + fileName)
end

File From System

This function creates a new file instance by converting the specified path name string into an abstract path name. If the specified string is empty, then the result is an empty abstract path name.

Syntax

1
<file File> := File.fromSystem(<pathname String>)

Returns
The new file instance.

Parameter

  • pathname - The path's name

Example 1 - Allocating the File with Its Global Path from the System

1
2
3
stepdef "assert file {} exists in the Project root folder"
    assert File.fromSystem("/home/user/intaQt-Projects/TestProject01/" + fileName)
end

Example 2 - Creating a File with a Temporary Path

1
2
3
4
stepdef "create temporary file {} in a temporary directory" / fileName /
    tempDir := File.createTempDir()
    testFile01 := File.fromSystem(tempDir.getPath() + File.separator() + fileName)
end

File Relative to Test

This function returns the file from the current execution context's feature folder.

Syntax

1
<file File> := File.relativeToTest(<path String>)

Returns
The specified file.

Parameter

  • path - The relative path to the feature folder

Example

1
2
3
4
stepdef "assert test directory"
    assert File.relativeToTest("x").toString()
        .endsWith("../projects/builtins-tests/01_features/file-builtin/x")
end

File Relative to User

This function returns the file from the user home folder.

Syntax

1
<file File> := File.relativeToUser(<path String>)

Returns
The specified file.

Parameter

  • path - The relative path to the user home folder

Example

1
2
3
4
stepdef "assert user directory"
    assert File.relativeToUser("x").toString()
        .equals("/Users/QiTASC/x")
end

Simplify Path

Returns the lexically cleaned form of the path name, usually (but not always) equivalent to the original.

Syntax

1
<result String> := File.simplifyPath(<pathname String>)

Returns
The lexically-cleaned form of the path name.

Parameter

  • pathname - The file path

The following heuristics are used:

  • Empty string becomes .

  • . remains as /.

  • Fold out ./

  • Fold out ../ when possible

  • Collapse multiple slashes

  • Delete trailing slashes (unless the path is just /)

These heuristics do not always match the file system's behavior. For example, simplifyPath will change the path a/../b to b. If a is a symlink to x, a/../b may refer to a sibling of x, rather than the sibling of a referred to by b.

Example

1
2
3
stepdef "assert simplified path of {} equals to {}" / path, simplifiedPath /
    assert simplifiedPath = File.simplifyPath(path)
end

Create

Create Parent Directories

This function creates any necessary but nonexistent parent directories of the specified file.

Syntax

1
File.createParentDirs(<file (String or File)>)
Parameter

  • file - The input file's identifier

Example

1
2
3
4
stepdef "create parent directories for {}" / fileName /
    fromFile := File.fromProject("../TestProject01/" + fileName)
    File.createParentDirs(file)
end

Note: If this operation fails, it may have succeeded in creating some (but not all) of the necessary parent directories.

Create Temporary Directory

This function automatically creates a new directory somewhere beneath the system's temporary directory. Use this method instead of File.createTempFile(String, String) when creating a directory instead of a file.

Note: This method assumes that the temporary volume is writable, has free inodes and free blocks, and that it will not be called thousands of times per second.

Syntax

1
<dir File> := File.createTempDir()

Returns
The new temporary directory.

Example

1
2
3
4
stepdef "create a temporary directory and print its path"
    tempDir := File.createTempDir()
    println(tempDir.getPath())
end

Create Temporary File

This method creates a temporary file in either the default directory or a specified directory. In both cases, the specified prefix and suffix are used to generate the file's name.

Important! A common mistake is to call createTempFile, delete the file and create a directory in its place. This leads a race condition, which can be exploited to create security vulnerabilities, especially when executable files written into the directory.

Syntax

1
<tempFile File> := File.createTempFile(<prefix String>, <suffix String>, <directory (String or File)>)

Returns
An abstract pathname, representing a newly-created empty file.

Parameters

  • prefix - The prefix to be used in generating the file's name

    • It must be at least three characters long
    • If it is too long, it will be truncated
  • suffix - The suffix to be used in generating the file's name

    • If null, .tmp will be used
    • If the suffix is too long, it will be truncated
  • directory (Optional) - The directory where the file is to be created, or null if the default temporary file directory is to be used

Example

1
2
3
4
stepdef "create a temporary file with prefix {} in folder of the file {}" / prefix, fileName /
    projectFile := File.fromProject("../TestProject01/" + fileName)
    tempFile := File.createTempFile(prefix, ".txt", projectFile.getParentFile())
end

Note: If the directory argument is null then the system-dependent default temporary file directory will be used. The default temporary file directory is specified by the system property, java.io.tmpdir.

  • On Unix systems, the default value of this property is typically /tmp or /var/tmp.

  • On Windows systems, it is typically C:\\WINNT\\TEMP.

  • A different value may be specified to this system property when the Java virtual machine is invoked. Programmatic changes to this property are not guaranteed to have any influence upon the temporary directory used by this method.

Touch File

This method creates an empty file or updates the last updated timestamp with the Unix command of the same name.

Syntax

1
File.touch(<file (String or File)>)

Parameter

  • file - The file to create or update

Example

1
2
3
4
5
6
7
stepdef "assert modified timestamp of touched file {} changed" / fileName /
    file := File.fromProject("../TestProject01/" + fileName)
    oldTimestamp := file.lastModified()
    delay(1)
    File.touch(file)
    assert oldTimestamp < file.lastModified()
end

Delete File

The following function deletes a file or a directory from the file system using intaQt languages.

Syntax

1
<isDeleted Boolean> := File.delete(<dir String>)

Returns
true if a file or a directory is successfully deleted, false otherwise.

Parameter

  • dir - An identifier to a path or a directory

In the following example, the File.delete method searches for a string, which can either represent a directory or a path and deletes it.

Example

1
2
3
4
stepdef "delete file {}" / fileName /
    myFile := File.fromProject("/externalFiles/" + fileName)
    File.delete(myFile)
end

Note: Even if the file or the directory does not exist, fromProject() will create a File instance. This will force the return value of the delete() function to be true even there is no directory or file in the first place.

Equals File

This checks if two files contain the same amount of bytes.

Syntax

1
<isEqual Boolean> := File.equal(<file1 (String or File)>, <file2 (String or File)>)

Returns
true if files contain the same amount of bytes as each other, false otherwise.

Parameters

  • file1 - The first file to compare

  • file2 - The file to compare the first file to

Example

1
2
3
4
5
6
stepdef "assert file {} equals to {}" / fileName1, fileName2 /
  file1 := File.fromProject("/TestProject01/" + fileName1)
  file2 := File.fromProject("/TestProject01/" + fileName2)
  isEqual := File.equal(file1, file2)
  assert isEqual
end

File Extension

This function returns the file extension of the specified file name, or an empty string if the file has no extension. The extension's dot (.) is not included in the result.

Syntax

1
File.getFileExtension(<fileName String>)

Parameters

  • extension - The object that holds the extension

  • fileName - The name of the file

Example

1
2
3
4
5
6
stepdef "assert extension of configuration file {} equals to conf" / confFileName /
    myFile := File.fromProject("../TestProject01/" + confFileName)
    // Using getName() to get the String name of the file instance 'myFile'
    extension := File.getFileExtension(myFile.getName())
    assert "conf" = extension ! "The extensions do not match"
end

File Separator

This function returns the system-dependent name separator character as a string. For example, "/" or "\".

Syntax

1
File.separator()

Example

1
2
3
4
stepdef "create platform independent filepath {}" / fileName /
    dir := File.createTempDir()
    file := File.fromSystem(dir.getPath() + File.separator() + fileName)
end

Get Name Without Extension

This method retrieves a file's name without its extension or path. This is similar to the basename Unix command. The result does not include the ".".

Syntax

1
<name String> := File.getNameWithoutExtension(<file String>)

Returns
The file name without its file extension or path.

Parameter

  • file - The name of the file to trim the extension from
    • This can be a fully qualified file name (including a path) or a file name

Example

1
2
3
stepdef "assert name of file {} without extension equals to {}" /fileName, fileNameWOE/
    assert fileNameWOE = File.getNameWithoutExtension(fileName)
end

Move File

This function can rename a file and/or move it to a different directory.

Syntax

1
File.move(<from (String or File)>, <to (String or File)>)

Parameters

  • from - The source file

  • to - The destination file

    • This must be the target path for the moved file itself

Example

1
2
3
4
5
6
stepdef "move file to another folder"
    fromFile := File.fromProject("testProject.conf")
    toFile := File.fromProject("/externalFiles/newText.txt")
    File.move(fromFile.getPath(),
        toFile.getParentFile() + File.separator() + fromFile.getName())
end

Path Separator

This function returns the system-dependent path separator character. For example, : or ;.

Syntax

1
<pathSeparator String> := File.pathSeparator()

Returns
The path separator.

Example

1
2
3
stepdef "print path separator"
    println(File.pathSeparator())
end

Read First Line

This function reads the first line from a file by either using the specified charset or the default charset. It returns the first line, or null if the file is empty. With both methods, the line does not include line termination characters, but does include other leading and trailing whitespaces.

Syntax

1
<result String> := File.readFirstLine(<file (String or File)>, <charset String>)

Returns
The line read by the given method.

Parameters

  • file - The file to read from

  • charset (Optional) - The charset used to decode the input stream

Example 1 - Using the Specified Charset

1
2
3
4
stepdef "assert first line in {} equals to {}" / fileName, firstLine /
    file := fromProject(fileName)
    assert firstLine := File.readFirstLine(file, "UTF-8")
end

Example 2 - Using the Default Charset

1
2
3
4
stepdef "assert first line in {} equals to {}" / fileName, firstLine /
    file := fromProject(fileName)
    assert firstLine := File.readFirstLine(file)
end

Read All Lines

This function reads all lines from a file by either using the specified charset or the default charset and returns a mutable List containing all the lines. In both cases, the lines do not include line-termination characters, but do include other leading and trailing whitespace.

Syntax

1
<lines List<String>> := File.readLines(<file (String or File)>, <charset String>)

Returns
The list containing all read lines.

Parameters

  • file - The file to read from

  • charset (Optional) - The charset used to decode the input stream

Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
stepdef "assert lines in {} equals to {}" / fileName, linesSeparatedByHash /
    file := File.fromProject(fileName)
    setContextObject("myFile", file)
    retrievedFile:= getContextObject("myFile", "UTF-8")
    expectedLines := linesSeparatedByHash.split("#")
    newLines := []

    for line in expectedLines
         newLines.add(line)
    end

    lines := File.readLines(file)
    assert lines.size() = newLines.size()

    for lineIndex, line in expectedLines
         assert line = lines[lineIndex]
    end
end

Read To String

This function reads all lines from a file and returns a string containing all the characters from the file. This can be done by either using the specified charset or the default charset. It returns a string containing all the characters from the file.

Syntax

1
<result String> := File.readToString(<file (String or File)>, <charset String>)

Returns
A string containing all the characters from the file.

Parameters

  • file - The file to read from

  • charset (Optional) - The charset used to decode the input stream

Example 1 - Using the Specified Charset

1
2
3
4
stepdef "Read content in file {}" / fileName /
    file := File.fromProject(fileName)
    fileContent = File.readToString(file, "UTF-8")
end

Example 2 - Using the Default Charset

1
2
3
4
stepdef "Read content in file {} using default charset" / fileName /
    file := File.fromProject(fileName)
    fileContent = File.readToString(file)
end

Write

The write() function provides the functionality to replace all characters in a file using the specified charset or the default charset.

Syntax

1
File.write(<from String>, <to (String or File)>, <charset String>)

Parameters

  • from - The characters being written to a file

  • to - The destination file

  • charset (Optional) - The specified charset

Example 1 - Using the Specified Charset

1
2
3
stepdef "write {} to {}" / content, fileName /
    file := File.fromProject("../TestProject01/" + fileName)
    File.write(content, file, "UTF-8")

Example 2 - Using the Default Charset

1
2
3
4
stepdef "write {} to {} using the default charset" / content, fileName /
    file := File.fromProject("../TestProject01/" + fileName)
    File.write(content, file)
end

Append

There are two append methods. The first method appends a character sequence to a file using the specified charset. The second method appends a character sequence to a file using the default charset.

Note: The default charset is determined during virtual machine startup and typically depends upon the locale and charset of the underlying operating system.

Syntax

1
File.append(<from String>, <to (String or File)>, <charset String>)

Parameters

  • from - The character sequence to append

  • to - The destination file or its path

  • charset (Optional) - The charset used to encode the output stream

Example 1 - Using the Specified Charset

1
2
3
4
5
6
stepdef "append text {} to the file {}" / text, fileName /
    // Get a file with the name "fileName" located in the main TestProject01 folder
    testFile := File.fromSystem("/home/user/intaQt-Projects/TestProject01/" + fileName)
    // Append the file with the predefined text
    File.append(text, testFile, "UTF-8")
end

Example 2 - Using the Default Charset

1
2
3
4
5
stepdef "append another text {} to the file {}" / text, fileName /
    // Using the double dot indicates the parent directory
    testFile := File.fromProject("../TestProject01/" + fileName)
    File.append(text, testFile)
  end

Note: More information is available in Execution and Language Context Built-ins.

Copy

This function copies all bytes from one file to another. It only works with local files. To copy files to or from remote machines, use Copy Built-ins.

Syntax

1
File.copy(<from (String or File)>, <to (String or File)>)

Parameters

  • from - The source file

  • to - The destination file

Example

1
2
3
4
5
stepdef "copy {} to {}" / from, to /
    fromFile := File.fromProject("../TestProject01/" + from)
    toFile := File.fromProject("../TestProject01/" + to)
    File.copy(fromFile, toFile)
end

Text File Chunking

The chunk method parses text files of any size into chunks. This consists of:

  • The file to chunk.

  • A function that takes a string (a line from the file) and returns true if the string is a line that matches the start of a chunk.

  • A callback function that has the chunks of the file passed to it as they are encountered.

Syntax

1
2
File.chunk(<inputFile File>, <chunkStart FunctionRef(String)>,
    <forEachChunk FunctionRef(List<String>)>)

Parameters

  • inputFile - The file to be parsed

  • chunkStart - The function that marks the start of the chunk

  • forEachChunk - The function that passes each chunk of lines from the file

Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
stepdef "check that log file {} has correct number of chunks" / f1 /
    inputFile := File.fromProject(f1)

    LogFileReactor.init(regex(" \\[[\\w\\d]+\\] "))

    File.chunk(inputFile,
        LogFileReactor::startOfChunk,
        LogFileReactor::forEachChunk)

    assert LogFileReactor.theCount = 3
end

In the example stepdef above, a file is opened. Next, reactor calls a Regex, using Regex Built-ins. Then, the File.chunk method is called, passing the input file and interpreting whether or not the specified string matches the start of a chunk. Finally, an assertion is made to check the count of the chunks.

Reactor Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
reactor LogFileReactor

    func init(regex)
        LogFileReactor.theCount := 0
        LogFileReactor.startOfChunkRegex := regex
    end

    func startOfChunk(line)
        return startOfChunkRegex.containsMatchIn(line)
    end

    func forEachChunk(lines)
        theCount := theCount + 1
    end

end

In the example above, the init method sets up the count and internally stores the regex. The startOfChunk function checks that there is at least one match for the regex in the line. Alternatively, the [Regex Built-ins](Regex matches function can check that the Regex matches the entire line.

When the Stepdef invokes the chunk method, the startOfChunk method is called for each line, and chunks are collected together. Once a complete chunk has been found, it will be passed to the forEachChunk method, where assertions (or storage of data for later assertions as in this case) may take place.

Note: Creating the regex a single time and passing it is more efficient than creating it each time a line is read: The startOfChunk will be called for each line.

File Walking

File walking allows users to recursively visit all files in a directory and perform filtering and other operations via callbacks on specified files.

Syntax

1
2
File.walk(<directory File>, <onEach FunctionRef>, <fileWalkDirection Boolean>,
    <shouldEnter File>, <onLeave File>)

Parameters

  • directory - The directory within which the files will be walked

  • onEach - The function that will be called for each file

  • fileWalkDirection (optional) - Specifies the direction to walk through the files in

    • Default is set to topDownDirection, which searches depth-first where the directory is visited before its files
    • bottomUpDirection searches breadth-first, where the directory is visited after its files
  • shouldEnter (optional)

    • true if the file should be walked
    • false otherwise
  • onLeave (optional) - This allows operations to be performed on every directory once it and its files have been visited

Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
stepdef "list files in directory {}" / q2 /
    directoryFile := File.fromProject(q2)
    setContextObject("files", [])
    File.walk(directoryFile, FileMatcher::onEach, File.topDownDirection)
    files := getContextObject("files")
 end

model FileMatcher
    func onEach(file)
        if file.name.contains("product_list") and file.name.endsWith(".xml") then
            getContextObject("files").add(file)
        end
    end
end

The example above gets a list of XML files with a "product_list" string in their names from a directory.

File Walking - Sorted Walk

The sortedWalk function walks the directory, using a comparator to specify the order in which the files are passed to the callback. sortedWalk may compare by name, or apply a customizable order in which files are provided to the callback. Customization allows for, for example:

  • Defining which directories to enter, and in what order.

  • Defining the order in which files will be walked within each directory, e.g., sorting myMusic123.mp3 and myMusic567.mp3 in numerical order first, then by alphabetical order.

Syntax

1
file.sortedWalk(<directory File>, <comparatorFunction (File, File)  Number>, <direction FileWalkDirection>, <shouldEnter (File)  Boolean>, <onlyFiles Boolean>)

Parameters

  • directory - The directory within which the files will be walked

  • comparatorFunction - A comparator function, which takes two files, and returns an Integer result

    • The result should be a negative integer, zero or a positive integer for the cases where the first file should be considered less than, equal to, or greater than the second
    • Two convenience constructors are provided:
  • direction - The direction in which to walk the directory, which may be one of:

    • File.topDownDirection - Starts from the top-level
    • File.bottomUpDirection - Starts from the bottom level
  • shouldEnter (optional)

    • true if the directory should be walked
    • false otherwise
  • onlyFiles (optional)

    • true (default) only retrieves files
    • false also retrieves directories

Example 1 - Sort by Name

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
stepdef "test of file walking"
    file := File.fromSystem("/Users/user/Desktop/files")
    File.sortedWalk(file, File.compareByName(File.ascending), Filewalktest::onFileFound)
end

model Filewalktest
    func onFileFound(file)
        println(file.name)
    end
end

Example 2- Customized Sorting

1
2
3
4
5
6
7
stepdef "test of sorted file walking"
    file := File.fromSystem("/Users/user/Desktop/files")
    File.sortedWalk(file, File.compareByNameParts(regex("(\\w)(\\d+).*"),
                           [ File.namePart(2, true, File.ascending),
                           File.namePart(1, false, File.descending)]),
                           Filewalktest::onFileFound)
end

In the above example, a comparator is created that sorts ascending by the second group of a regex expression. If this is equal between files, then it will sort by the first group in a descending order.

Sorted Walk - Compare By Name

compareByName compares the files by name.

Syntax

1
File.compareByName(File.<order FileSortingOrder> )

Parameter

  • order - One of File.ascending or File.descending

Example

1
File.sortedWalk(file, File.compareByName(File.ascending), Filewalktest::onFileFound)

Sorted Walk - Compare By Name Parts

ComparebyName takes a namePart, and a RegexWrapper, which splits the file/directory names according to the defined pattern.

Syntax

1
File.CompareByNameParts(<regex RegexWrapper>,[<List <NamePart>, ...])

Parameters

  • regex - The Regex pattern used to split the files/directories by name

  • List - The list of nameParts

Example

1
2
3
4
File.compareByNameParts(regex("(\\w)(\\d+).*"),
                       [ File.namePart(2, true, File.ascending),
                       File.namePart(1, false, File.descending)]),
                       Filewalktest::onFileFound)

Sorted Walk - Name Parts

namePart parses the Regex group, created in the compareByNameParts function, by its assigned index. It is then converted into a number and sorted in ascending or descending order.

Syntax

1
File.namePart(<index Number>, <isNumeric Boolean>, <fileSortingOrder Order>)

Parameters

  • index - A user-assigned number that indicates the Regex group

  • isNumeric

    • true for to parse the Regex group as an integer
    • false otherwise
  • fileSortingOrder - The order in which to sort the files/directories

    • FileSortingOrder.ASC - Sorts in ascending order (default)
    • FileSortingOrder.DES - Sorts in descending order

Example

1
File.namePart(2, true, File.ascending), File.namePart(1, false, File.descending)

Note: The list of nameParts are sorted by the order in which they appear within the function. In the example above, the namePart with index 2 is sorted first.