#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.
FileStream :: struct {
handle: _fs_impl.File;
}
File: fs.bl
FILE_INVALID :: _fs_impl.FILE_INVALID
Invalid file handle. This can be used for file handle validation.
File: fs.bl
OpenFileMode :: enum {
READ;
WRITE;
APPEND;
CREATE;
}
Specify operation with opened file.
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
open_file :: fn (filepath: string_view, mode : OpenFileMode: OpenFileMode.READ) (_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.
#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
close_file :: fn (stream: *FileStream) #inline
Close previously openned file stream.
File: fs.bl
create_file :: fn (filepath: string_view) Error
Create new file if it does not exists. Otherwise does nothing.
File: fs.bl
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
copy_file :: fn (src: string_view, dest: string_view, override :: false) 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
file_uid :: fn {
fn (stream: *FileStream) (_0: u64, _1: Error);
_fs_impl.get_uid_by_name;
}
Returns file id.
File: fs.bl
file_size :: fn (stream: *FileStream) (_0: s64, _1: Error)
Returns size in bytes of stream file or an error.
File: fs.bl
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
create_all_dir :: fn (dirpath: string_view) Error
File: fs.bl
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
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: *FileVisitInfo, 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
FileVisitInfo :: struct {
is_directory: bool;
filename: string_view;
filepath: string_view;
step_into_directory: bool;
}
Information about file entry.
is_directory - True in case the entry is a directory.filename - File or directory name.filepath - File or directory full path.step_into_directory - In case the file visitor is in recursive mode the visitor callback might change this
value to false in case the current directory should be ignored.Note:
Does not take any effect in case the leaf_first is set in visit options.
File: fs.bl
VisitOpt :: struct {
recursive: bool;
leaf_first: bool;
}
Visit file options used in visit_files.
recursive - Visit all subfolders when true.leaf_first - Visit the most nested files first.File: fs.bl
visit_files :: fn {
fn (dirpath: string_view, opt: VisitOpt, ctx: *?T, visitor: *fn (info: *FileVisitInfo, ctx: *T) Error) Error;
fn (dirpath: string_view, opt: VisitOpt, visitor: *fn (info: *FileVisitInfo) 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: *FileVisitInfo, ctx: *T) Error) Error #inline
fn (dirpath: string_view, opt: VisitOpt, visitor: *fn(info: *FileVisitInfo) Error) Error #inline
#import "std/fs"
main :: fn () s32 {
using std;
visitor :: fn (info: *FileVisitInfo, 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
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
validate_filename :: fn (name: string_view) bool #inline
Checks whether name is valid file name on current platform.
File: fs.bl
file_exist :: fn (filepath: string_view) bool #inline
Check whether file or directory exists.
File: fs.bl
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
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.
| 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
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.
| 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
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
set_cwd :: fn (path: string_view) Error #inline
Sets current working directory and return OK on success, otherwise return error.
File: fs.bl
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
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