File System

#import "std/fs"

File system module for manipulation with files and directories. This module provides an abstraction over operating system APIs such as creating files and directories, reading and writing, and scanning the filesystem.

std.FileStream

FileStream :: struct {
    handle: _fs_impl.File;
 }

File: fs.bl

std.FILE_INVALID

FILE_INVALID :: _fs_impl.FILE_INVALID

Invalid file handle. This can be used for file handle validation.

File: fs.bl

std.OpenFileMode

OpenFileMode :: enum {
    READ;
    WRITE;
    APPEND;
    CREATE;
}

Specify operation with opened file.

Variants

  • READ - Open file for reading.
  • WRITE - Open file for writing and truncate its content.
  • APPEND - Open file for appending (keeps current content).
  • CREATE - Create file if it does not exist.

File: fs.bl

std.open_file

open_file :: fn (filepath: string_view, mode : OpenFileMode: ) (_0: FileStream, _1: Error) #inline

Open an file specified by filepath. Function return file stream and OK status when file was opened, otherwise return invalid stream and proper error. Stream must be closed by close_file call.

File open mode is optional, any combination of OpenFileMode can be used. When Create mode is specified, new file is created on filepath only if it does not exist, otherwise already existing file is used. Read mode is used as default when neither Read, Write or Append is specified.

Example

#import "std/fs"

main :: fn () s32 {
    using std;

    stream, open_err :: open_file(#file);
    defer close_file(&stream);
    if open_err { 
        print_err(open_err); 
        return 1; 
    }

    str := str_new();
    defer str_delete(&str);
    read_bytes, read_err :: read_string(&stream, &str);
    if read_err { 
        print_err(read_err);
        return 2;
    }
    print("read % bytes\n", read_bytes);
    print("%\n", str);
    return 0;
}

File: fs.bl

std.close_file

close_file :: fn (stream: *FileStream)  #inline

Close previously openned file stream.

File: fs.bl

std.create_file

create_file :: fn (filepath: string_view) Error

Create new file if it does not exists. Otherwise does nothing.

File: fs.bl

std.remove_file

remove_file :: fn (filepath: string_view) Error #inline

Try to remove file specified by filepath and return OK on success, otherwise return error.

File: fs.bl

std.copy_file

copy_file :: fn (src: string_view, dest: string_view, override :: ) Error #inline

Copy existing file from src to dest and override existing file in destination if override is true. Return ok or error.

The destination file is created if it does not exist.

Note

The src and dest path can be relative path to current working path set by set_cwd.

File: fs.bl

std.file_uid

file_uid :: fn { 
    fn (stream: *FileStream) (_0: u64, _1: Error); 
    _fs_impl.get_uid_by_name; 
}

Returns file id.

File: fs.bl

std.file_size

file_size :: fn (stream: *FileStream) (_0: s64, _1: Error)

Returns size in bytes of stream file or an error.

File: fs.bl

std.create_dir

create_dir :: fn (dirpath: string_view) Error #inline

Create new directory and return OK on success. This function does not create directories recursively.

File: fs.bl

std.create_all_dir

create_all_dir :: fn (dirpath: string_view) Error

File: fs.bl

std.remove_dir

remove_dir :: fn (dirpath: string_view) Error #inline

Remove directory specified by dirpath and return OK on success, otherwise return an error.

File: fs.bl

std.Info

Info :: struct {
    is_directory: bool;
    filename: string_view;
    filepath: string_view;
 }

Filesystem entry description.

Members

  • is_directory - True in case the entry is a directory.
  • filename - File or directory name.
  • filepath - File or directory full path.

File: fs.bl

std.remove_all_dir

remove_all_dir :: fn { 
    impl_remove_all_dir; 
    impl_remove_all_dir_with_filter; 
    impl_remove_all_dir_with_filter_and_context; 
}

Remove (even non-empty) directory specified by dirpath and return OK on success, otherwise return an error. Root directory is removed if remove_root is true. Custom file filter function can be specified as needed.

Overloads:

fn (dirpath: string_view, remove_root := true) Error #inline
fn (dirpath: string_view, remove_root: bool, filter: *fn(info: *Info, ctx: *?T) bool, ctx: *T = null) Error

When the filter callback is specified, it's called for each visited file or directory. Returning true means the entry should be deleted.

Warning

When some files are excluded by the filter function the parent directory cannot be removed (it's not empty). Be careful excluding directories.

Note

This function recursively remove all nested folders and files in specified sub tree so it can be expensive.

File: fs.bl

std.VisitOpt

VisitOpt :: struct {
    recursive: bool;
    leaf_first: bool;
 }

Visit file options used in visit_files.

Members

  • recursive - Visit all subfolders when true.
  • leaf_first - Visit the most nested files first.

File: fs.bl

std.visit_files

visit_files :: fn { 
    fn (dirpath: string_view, opt: VisitOpt, ctx: *?T, visitor: *fn (info: *Info, ctx: *T) Error) Error; 
    fn (dirpath: string_view, opt: VisitOpt, visitor: *fn (info: *Info) Error) Error; 
} #inline

Visit all files and directories in dirpath with specified visitor callback called for each found file entry. Optional context ctx pointer can be passed into the function.

Overloads:

fn (dirpath: string_view, opt: VisitOpt, ctx: *?T, visitor: *fn(info: *Info, ctx: *T) Error) Error #inline
fn (dirpath: string_view, opt: VisitOpt, visitor: *fn(info: *Info) Error) Error #inline

Example

#import "std/fs"

main :: fn () s32 {
    using std;

    visitor :: fn (info: *Info, list: *[..]string) Error {
        using std;
        if info.is_directory { return OK; }
        _, ext :: path_splitext(info.filename);
        if str_match(ext, ".bl") {
            array_push(list, str_new(info.filepath));
        }
        return OK;
    };

    list: [..]string;
    defer array_terminate(&list);
    cwd :: get_cwd();
    defer str_delete(&cwd);
    err :: visit_files(cwd, VisitOpt.{ recursive = true }, &list, &visitor);
    if err { panic(err); }

    loop i := 0; i < list.len; i += 1 {
        print_log("FILE: %\n", list[i]);
        str_delete(&list[i]);
    }

    return 0;
}

File: fs.bl

std.is_directory

is_directory :: fn (path: string_view) (_0: bool, _1: Error) #inline

Check whether path points to valid directory. Returns error in case the check failed.

File: fs.bl

std.validate_filename

validate_filename :: fn (name: string_view) bool #inline

Checks whether name is valid file name on current platform.

File: fs.bl

std.file_exist

file_exist :: fn (filepath: string_view) bool #inline

Check whether file or directory exists.

File: fs.bl

std.path_normalize

path_normalize :: fn (filepath: *string) Error #inline

Try to normalize filepath, basically try to remove all relative path nodes .. and .. Path must be valid path (existing) on system. Original filepath is extended with current working directory. Function return OK on success or proper error on fail. Original string is not modified when error occurs.

File: fs.bl

std.path_split

path_split :: fn (filepath: string_view) (head: string_view, tail: string_view)

Split input filepath into head and tail components. The tail is the last filepath component and the head is everything before. Only unix / path delimiters are supported. The tail component never contains path separators.

Example

filepath head tail
C:/foo/bar/file.txt C:/foo/bar/ file.txt
file.txt - file.txt
/usr/local/.hidden.file /usr/local/ .hidden.file
/ / -
C:/ C:/ -

Note

Returned components may not be zero terminated.

File: fs.bl

std.path_splitext

path_splitext :: fn (filepath: string_view) (head: string_view, ext: string_view)

Split input filepath into head and ext components. The ext is the file extension and the head is everything before.

Example

filepath head ext
C:/foo/bar/file.txt C:/foo/bar/file .txt
file.txt file .txt
/usr/local/.hidden.file /usr/local/.hidden .file
/ / -
C:/ C:/ -

Note

Returned components may not be zero terminated.

File: fs.bl

std.get_cwd

get_cwd :: fn () string #inline

Try to obtain current working directory, result must be released by std.str_delete. Path does not contain last path separator.

File: fs.bl

std.set_cwd

set_cwd :: fn (path: string_view) Error #inline

Sets current working directory and return OK on success, otherwise return error.

File: fs.bl

std.get_home

get_home :: fn () string #inline

Try to obtain system home directory, result must be released by std.str_delete. Path does not contain last path separator.

File: fs.bl

std.get_tmp

get_tmp :: fn () string #inline

Try to obtain system temporary directory, result must be released by std.str_delete. Path does not contain last path separator.

File: fs.bl