#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 #base Stream {
handle: _File;
}
File: fs.bl
FILE_INVALID :: _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"
#import "std/print"
#import "std/io"
#import "std/string"
main :: fn () s32 {
stream :: open_file(#file) catch {
print_err($);
return 1;
};
defer close_file(&stream);
str: string;
defer str_terminate(&str);
read_bytes :: read_string(&stream, &str) catch {
print_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
read_entire_file :: fn (filepath: string_view, allocator : *Allocator: null) (_0: []u8, _1: Error)
Reads content of entire file on filepath into array of bytes. Allocator can be specified optionally, in case it's null
default application context allocator will be used.
Returned array might require explicit destruction by calling free_slice depenting on allocator being used.
Use application_context.temporary_allocator in case the resulting content is not supposed to be persistent.
File: fs.bl
write_entire_file :: fn (filepath: string_view, content: []u8, mode :: ) Error
Write entire content into the file on filepath.
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);
_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"
#import "std/print"
#import "std/string"
#import "std/array"
main :: fn () s32 {
visitor :: fn (info: *FileVisitInfo, list: *[..]string) Error {
if info.is_directory { return OK; }
_, ext :: path_splitext(info.filename);
if str_match(ext, ".bl") {
array_push(list, str_make(info.filepath));
}
return OK;
};
list: [..]string;
defer array_terminate(&list);
cwd :: get_cwd();
defer str_terminate(&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_terminate(&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:/ | - |
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:/ | - |
File: fs.bl
get_cwd :: fn () string #inline
Try to obtain current working directory, result must be released by str_terminate. 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 str_terminate. 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 str_terminate. Path does
not contain last path separator.
File: fs.bl