# Files

## File Exists

#### Definition

```swift
fileExists(path: string) -> boolean
```

#### Usage example

```lua
print(fileExists('my_file.lua'))
-- true
```

#### Source code

```lua
function fileExists(path)
    local f = io.open(path, 'r')
    return f ~= nil and io.close(f)
end
```

## Get Files Recursively

#### Definition

```swift
getFilesRecursive(path: string, maxDepth: integer) -> table
```

```lua
--
-- getFilesRecursive()
--
-- @param  string    path      The starting path: Default: '.' (mod's root folder)
-- @param  integer   maxDepth  The maximum depth allowed. Default: -1 (unlimited)
--
getFilesRecursive('.', -1)
```

#### Usage example

```lua
local files = getFilesRecursive('.', 2)
```

```
files = {
    "./includes/module-1.lua",
    "./includes/module-2.lua",
    "./includes/sub-folder/sub-module-1.lua",
    "./init.lua",
}
```

#### Source code

```lua
function getFilesRecursive(path, maxDepth, depth, storage)

    -- vars
    path = path or '.'
    maxDepth = maxDepth or -1
    depth = depth or 0
    storage = storage or {}

    -- validate maxDepth
    if maxDepth ~= -1 and depth > maxDepth then
        return storage
    end

    -- sanitize path leading "."
    if not string.find(path, '^%.') then
        path = '.' .. path
    end

    -- sanitize path leading double "//"
    if string.find(path, '^%.//') then
        path = string.gsub(path, '^%.//', './')
    end

    -- get dir/files
    local files = dir(path)

    -- validate files
    if not files or (type(files) == 'table' and #files == 0) then
        return storage
    end

    -- loop files
    for _, file in ipairs(files) do

        -- directory
        if file.type == 'directory' then
            getFilesRecursive(path .. '/' .. file.name, maxDepth, depth + 1, storage)

        -- lua file
        elseif string.find(file.name, '%.lua$') then
            table.insert(storage, path .. '/' .. file.name)
        end

    end

    return storage

end
```

## Get Folders Recursively

#### Definition

```swift
getFoldersRecursive(path: string, maxDepth: int) -> table
```

```lua
--
-- getFoldersRecursive()
--
-- @param  string    path      The starting path: Default: '.' (mod's root folder)
-- @param  integer   maxDepth  The maximum depth allowed. Default: -1 (unlimited)
--
getFoldersRecursive('.', -1)
```

#### Usage example

```lua
local folders = getFoldersRecursive('.', 2)
```

<pre><code><strong>folders = {
</strong>    "./includes",
    "./includes/sub-folder",
}
</code></pre>

#### Source code

```lua
function getFoldersRecursive(path, maxDepth, depth, storage)

    -- vars
    path = path or '.'
    maxDepth = maxDepth or -1
    depth = depth or 0
    storage = storage or {}

    -- validate maxDepth
    if maxDepth ~= -1 and depth > maxDepth then
        return storage
    end

    -- sanitize path leading "."
    if not string.find(path, '^%.') then
        path = '.' .. path
    end

    -- sanitize path leading double "//"
    if string.find(path, '^%.//') then
        path = string.gsub(path, '^%.//', './')
    end

    -- get dir/files
    local files = dir(path)

    -- validate files
    if not files or (type(files) == 'table' and #files == 0) then
        return storage
    end

    -- loop files
    for _, file in ipairs(files) do

        -- directory
        if file.type == 'directory' then
            table.insert(storage, path .. '/' .. file.name)
            getFoldersRecursive(path .. '/' .. file.name, maxDepth, depth + 1, storage)
        end

    end

    return storage

end
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://wiki.redmodding.org/cyber-engine-tweaks/snippets-examples/utilities/files.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
