1:- encoding(utf8).
    2:- module(
    3  file_ext,
    4  [
    5    append_directories/2,          % +Directories, -Directory
    6    cat/2,                         % +Out, +Files
    7    change_file_name_extension/3,  % ?FromFile, ?FromExtension, ?ToFile
    8    change_file_name_extension/4,  % ?FromFile, ?FromExtension, ?ToExtension, ?ToFile
    9    change_file_name_extensions/3, % ?FromFile, ?FromExtensions, ?ToFile
   10    change_file_name_extensions/4, % ?FromFile, ?FromExtensions, ?ToExtensions, ?ToFile
   11    compress_file/1,               % +FromFile
   12    compress_file/2,               % +FromFile, ?ToFile
   13    concatenate_files/2,           % +Files, +ConcatenatedFile
   14    convert_file/2,                % +File, +Format
   15    convert_file/3,                % +FromFile, +Format, ?ToFile
   16    create_directory/1,            % +Directory
   17    create_file_directory/1,       % +File
   18    decompress_file/2,             % +FromFile, +ToFile
   19    delete_files_by_extension/1,   % +Extension
   20    delete_files_by_extension/2,   % +Directory, +Extension
   21    delete_files_by_extensions/1,  % +Extensions
   22    delete_files_by_extensions/2,  % +Directory, +Extensions
   23    directory_file/2,              % +Directory, -File
   24    directory_file_path2/3,        % ?Directory, ?File, ?Path
   25    directory_parent/2,            % +ChildDirectory, -ParentDirectory
   26    directory_path/2,              % ?Directory, ?Path
   27    directory_path_recursive/2,    % +Directory, -Path
   28    directory_subdirectories/2,    % ?Directory, ?Subdirectories
   29    directory_subdirectory/2,      % +Directory, ?Subdirectory
   30    directory_subdirectory/3,      % +Directory, ?Local, ?Subdirectory
   31    file_call/2,                   % +File, Goal_1
   32    file_extension/2,              % +File, -Extension
   33    file_extensions/2,             % +File, -Extensions
   34    file_extensions_media_type/2,  % +Extensions, -MediaType
   35    file_is_fresh/2,               % +File, +LastModified
   36    file_line/2,                   % +File, -Line
   37    file_media_type/2,             % +File, -MediaType
   38    file_mode/2,                   % +File, +Mode
   39    file_name/2,                   % ?File, ?Name
   40    file_name_extension2/3,        % ?File, ?Name, ?Extension
   41    file_name_extensions/3,        % ?File, ?Name, ?Extensions
   42    file_size/2,                   % +File, -Size
   43    file_to_string/2,              % +File, -String
   44    guess_file_encoding/2,         % +File, ?Encoding
   45    home_directory/1,              % ?Directory
   46    is_dummy_file/1,               % +File
   47    is_empty_directory/1,          % +Directory
   48    is_empty_file/1,               % +File
   49    peek_file/3,                   % +File, +Size, -String
   50    read_from_file/2,              % +File, :Goal_1
   51    read_from_file/3,              % +File, :Goal_1, +Options
   52    read_write_file/2,             % +FromFile, :Goal_2
   53    read_write_file/3,             % +FromFile, :Goal_2, +Options
   54    read_write_file/4,             % +FromFile, :Goal_2, +ReadOptions, +WriteOptions
   55    read_write_files/3,            % +FromFile, +ToFile, :Goal_2
   56    read_write_files/4,            % +FromFile, +ToFile, :Goal_2, +Options
   57    read_write_files/5,            % +FromFile, +ToFile, :Goal_2, +ReadOptions, +WriteOptions
   58    recode_file/1,                 % +File
   59    recode_file/2,                 % +File, +FromEncoding
   60    recode_files/2,                % +FromFile, +ToFile
   61    recode_files/3,                % +FromFile, +FromEncoding, +ToFile
   62    sort_file/1,                   % +File
   63    sort_file/2,                   % +File, +Options
   64    touch/1,                       % +File
   65    working_directory/1,           % -Directory
   66    write_to_file/2,               % +File, :Goal_1
   67    write_to_file/3                % +File, :Goal_1, +Options
   68  ]
   69).   70:- reexport(library(filesex)).   71:- reexport(library(stream_ext)).

Additional support for working with files

*/

   77:- use_module(library(apply)).   78:- use_module(library(error)).   79:- use_module(library(lists)).   80:- use_module(library(readutil)).   81:- use_module(library(yall)).   82:- use_module(library(zlib)).   83
   84:- use_module(library(call_ext)).   85:- use_module(library(dict)).   86:- use_module(library(hash_ext)).   87:- use_module(library(media_type)).   88:- use_module(library(sort_ext)).   89:- use_module(library(stream_ext)).   90:- use_module(library(thread_ext)).   91
   92:- meta_predicate
   93    call_file_(+, +, 1, +),
   94    call_files_(+, +, +, +, 2, +, +),
   95    file_call(+, 1),
   96    read_from_file(+, 1),
   97    read_from_file(+, 1, +),
   98    read_write_file(+, 2),
   99    read_write_file(+, 2, +),
  100    read_write_file(+, 2, +, +),
  101    read_write_files(+, +, 2),
  102    read_write_files(+, +, 2, +),
  103    read_write_files(+, +, 2, +, +),
  104    write_to_file(+, 1),
  105    write_to_file(+, 1, +).  106
  107:- multifile
  108    error:has_type/2.  109
  110error:has_type(directory, Directory) :-
  111  var(Directory), !,
  112  instantiation_error(Directory).
  113error:has_type(directory, Directory) :-
  114  \+ exists_directory(Directory), !,
  115  existence_error(directory, Directory).
  116error:has_type(directory, Directory) :-
  117  error:has_type(atom, Directory).
  118error:has_type(media_type, media(Supertype/Subtype,Parameters)) :-
  119  maplist(error:has_type(atom), [Supertype,Subtype]),
  120  error:has_type(list(compound), Parameters).
 append_directories(+Directories:list(atom), -Directory:atom) is det
  128append_directories([], '/') :- !.
  129append_directories([H], H) :- !.
  130append_directories([H|T], Dir) :-
  131  append_directories_(H, T, Dir).
  132
  133append_directories_(Dir, [], Dir) :- !.
  134append_directories_(Dir1, [H|T], Dir3) :-
  135  append_directories(Dir1, H, Dir2),
  136  append_directories_(Dir2, T, Dir3).
 append_directories(+Directory1:atom, +Directory2:atom, -Directory:atom) is det
Returns the directory name obtained by concatenating the given directory names.

The empty atom in the first position indicates the root directory.

Does not ensure that any of the directories exist.

  148append_directories(Dir1, Dir2, Dir3) :-
  149  directory_subdirectories(Dir1, Subdirs1),
  150  directory_subdirectories(Dir2, Subdirs2a),
  151  remove_root_(Subdirs2a, Subdirs2b),
  152  append(Subdirs1, Subdirs2b, Subdirs3),
  153  directory_subdirectories(Dir3, Subdirs3).
  154
  155remove_root_([''|T], T) :- !.
  156remove_root_(L, L).
 cat(+Out:ostream, +Files:list(atom)) is det
  162cat(Out, Files) :-
  163  maplist(cat_file(Out), Files).
  164
  165cat_file(Out, File) :-
  166  read_from_file(File, {Out}/[In0]>>copy_stream_data(In0, Out)).
 change_file_name_extension(?FromFile:atom, ?ToExtension:atom, ?ToFile:atom) is det
  172change_file_name_extension(FromFile, ToExt, ToFile) :-
  173  change_file_name_extension(FromFile, _, ToExt, ToFile).
 change_file_name_extension(?FromFile:atom, ?FromExtension:atom, ?ToExtension:atom, ?ToFile:atom) is det
  181change_file_name_extension(FromFile, FromExt, ToExt, ToFile) :-
  182  file_name_extension(Base, FromExt, FromFile),
  183  file_name_extension(Base, ToExt, ToFile).
 change_file_name_extensions(?FromFile:atom, ?ToExtensions:list(atom), ?ToFile:atom) is det
  189change_file_name_extensions(FromFile, ToExt, ToFile) :-
  190  change_file_name_extensions(FromFile, _, ToExt, ToFile).
 change_file_name_extensions(?FromFile:atom, ?FromExtensions:list(atom), ?ToExtensions:list(atom), ?ToFile:atom) is det
  198change_file_name_extensions(FromFile, FromExt, ToExt, ToFile) :-
  199  file_name_extensions(Base, FromExt, FromFile),
  200  file_name_extensions(Base, ToExt, ToFile).
 compress_file(+FromFile:atom) is det
 compress_file(+FromFile:atom, +ToFile:atom) is det
compress_file(+FromFile:atom, -ToFile:atom) is det
  208compress_file(FromFile) :-
  209  compress_file(FromFile, _).
  210
  211
  212compress_file(FromFile, ToFile) :-
  213  (var(ToFile) -> file_name_extension(FromFile, gz, ToFile) ; true),
  214  read_write_files(FromFile, ToFile, copy_stream_data).
 concatenate_files(+Files, +ConcatenatedFile) is det
  220concatenate_files(Files, File) :-
  221  setup_call_cleanup(
  222    open(File, write, Out),
  223    concatenate_files0(Files, Out),
  224    close(Out)
  225  ).
  226
  227concatenate_files0([], _) :- !.
  228concatenate_files0([H|T], Out) :- !,
  229  setup_call_cleanup(
  230    open(H, read, In),
  231    copy_stream_data(In, Out),
  232    close(In)
  233  ),
  234  concatenate_files0(T, Out).
 convert_file(+File:atom, +Format:atom) is det
 convert_file(+FromFile:atom, +Format:atom, ?ToFile:atom) is det
See also
- Formats are ‘documented’ over at https://cgit.freedesktop.org/libreoffice/core/tree/filter/source/config/fragments/filters
- Encodings are ‘documented’ over at https://wiki.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Filter_Options
  247convert_file(File, Format) :-
  248  convert_file(File, Format, _).
  249
  250
  251convert_file(FromFile, Format, ToFile) :-
  252  call_must_be(convert_format, Format),
  253  from_to_file_(FromFile, [Format], ToFile),
  254  file_directory_name(ToFile, ToDir),
  255  process_create(
  256    path(libreoffice),
  257    ['--convert-to',Format,'--infilter=CSV:44,34,76,1','--outdir',ToDir,file(FromFile)],
  258    []
  259  ).
  260
  261convert_format(csv).
 create_directory(+Directory:atom) is det
  267create_directory(Dir) :-
  268  exists_directory(Dir), !.
  269create_directory(Dir) :-
  270  make_directory_path(Dir).
 create_file_directory(+Path) is det
Ensures that the directory structure for the given file exists.
  278create_file_directory(Path) :-
  279  (exists_directory(Path) -> Dir = Path ; directory_file_path(Dir, _, Path)),
  280  create_directory(Dir).
 decompress_file(+FromFile:atom, +ToFile:atom) is det
  286decompress_file(FromFile, ToFile) :-
  287  read_write_files(FromFile, ToFile, copy_stream_data).
 delete_files_by_extension(+Extension:atom) is det
 delete_files_by_extension(+Directory:atom, +Extension:atom) is det
  294delete_files_by_extension(Ext) :-
  295  working_directory(Dir),
  296  delete_files_by_extension(Dir, Ext).
  297
  298
  299delete_files_by_extension(Dir, Ext) :-
  300  format(atom(Wildcard1), "*.~a", [Ext]),
  301  directory_file_path(Dir, Wildcard1, Wildcard2),
  302  expand_file_name(Wildcard2, Files),
  303  maplist(delete_file, Files).
 delete_files_by_extensions(+Extensions:list(atom)) is det
 delete_files_by_extensions(+Directory:atom, +Extensions:list(atom)) is det
  310delete_files_by_extensions(Exts) :-
  311  working_directory(Dir),
  312  delete_files_by_extensions(Dir, Exts).
  313
  314
  315delete_files_by_extensions(Dir, Exts) :-
  316  threaded_maplist_1(delete_files_by_extension(Dir), Exts).
  317
  318
  319
  320% directory_file(+Directory:atom, -File:atom) is nondet.
  321%
  322% Non-deterministic variant of directory_files/2 that skips dummy
  323% files.
  324
  325directory_file(Dir, File) :-
  326  directory_files(Dir, Files),
  327  member(File, Files),
  328  \+ is_dummy_file(File).
 directory_file_path2(+Directory:atom, +File:atom, -Path:atom) is det
directory_file_path2(+Directory:atom, -File:atom, -Path:atom) is nondet
directory_file_path2(-Directory:atom, -File:atom, +Path:atom) is det
Instantiation pattern (+,-,-) is not supported by directory_file_path/3 from the standard library.
  339directory_file_path2(Dir, File, Path) :-
  340  ground(Dir), var(File), var(Path), !,
  341  directory_file(Dir, File),
  342  directory_file_path(Dir, File, Path).
  343directory_file_path2(Dir, File, Path) :-
  344  directory_file_path(Dir, File, Path).
 directory_parent(+ChildDirectory:atom, -ParentDirectory:atom) is det
  350directory_parent(Dir1, Dir2) :-
  351  directory_subdirectories(Dir1, Subdirs1),
  352  once(append(Subdirs2, [_], Subdirs1)),
  353  directory_subdirectories(Dir2, Subdirs2).
 directory_path(+Directory:atom, -Path:atom) is nondet
directory_path(-Directory:atom, +Path:atom) is det
  360directory_path(Dir, Path) :-
  361  directory_file(Dir, File),
  362  directory_file_path(Dir, File, Path).
 directory_path_recursive(+Directory:atom, -Path:atom) is nondet
  368directory_path_recursive(Dir, Path) :-
  369  directory_path(Dir, Path0),
  370  (   exists_directory(Path0)
  371  ->  directory_path_recursive(Path0, Path)
  372  ;   Path = Path0
  373  ).
 directory_subdirectories(+Directory:atom, -Subdirectories:list(atom)) is det
directory_subdirectories(-Directory:atom, +Subdirectories:list(atom)) is det
Occurrences of `. and .. in Directory' are resolved.

The empty atom in the first position indicates the root directory.

For absolute directory names the first subdirectory name is the empty atom.

  387directory_subdirectories(Dir, Subdirs2) :-
  388  ground(Dir), !,
  389  atomic_list_concat(Subdirs1, /, Dir),
  390  resolve_subdirectories(Subdirs1, Subdirs2).
  391directory_subdirectories(Dir, Subdirs1) :-
  392  resolve_subdirectories(Subdirs1, Subdirs2),
  393  atomic_list_concat(Subdirs2, /, Dir).
 directory_subdirectory(+Directory:atom, +SubDirectory:atom) is semidet
directory_subdirectory(+Directory:atom, -SubDirectory:atom) is nondet
  400directory_subdirectory(Dir, Subdir) :-
  401  directory_subdirectory(Dir, _, Subdir).
 directory_subdirectory(+Directory:atom, +Local:atom, +SubDirectory:atom) is semidet
directory_subdirectory(+Directory:atom, +Local:atom, -SubDirectory:atom) is semidet
directory_subdirectory(+Directory:atom, -Local:atom, -SubDirectory:atom) is nondet
  408directory_subdirectory(Dir, Local, Subdir) :-
  409  ground(Local), !,
  410  directory_file_path(Dir, Local, Subdir),
  411  exists_directory(Subdir).
  412directory_subdirectory(Dir, Local, Subdir) :-
  413  directory_path(Dir, Subdir),
  414  exists_directory(Subdir),
  415  directory_file_path(_, Local, Subdir).
 file_call(+File:atom, :Goal_1) is det
  421file_call(File, Goal_1) :-
  422  setup_call_cleanup(
  423    open(File, read, In),
  424    call(Goal_1, In),
  425    close(In)
  426  ).
 file_extension(+File:atom, -Extension:atom) is nondet
  432file_extension(File, Ext) :-
  433  file_extensions(File, Exts),
  434  member(Ext, Exts).
 file_extensions(+File:atom, -Extensions:list(atom)) is det
  440file_extensions(File, Exts) :-
  441  file_name_extensions(File, _, Exts).
 file_extensions_media_type(+Extensions:list(atom), -MediaType:media_type) is det
  447file_extensions_media_type(Exts, MediaType) :-
  448  member(Ext, Exts),
  449  media_type_extension(MediaType, Ext), !.
 file_is_fresh(+File:atom, +LastModified:nonneg) is det
  455file_is_fresh(File, LMod) :-
  456  exists_file(File),
  457  \+ is_empty_file(File),
  458  time_file(File, Sync),
  459  Sync > LMod.
 file_line(+File:atom, -Line:string) is nondet
  465file_line(File, Line) :-
  466  read_from_file(File, {Line}/[In0]>>stream_line(In0, Line)).
 file_media_type(+File:atom, -MediaType:media_type) is nondet
  472file_media_type(File, MediaType) :-
  473  file_extension(File, Ext),
  474  media_type_extension(MediaType, Ext).
 file_mode(+File:atom, +Mode:oneof([append,read,write])) is det
throws
- existence_error
- permission_error
  483file_mode(File, Mode) :-
  484  (   exists_file(File)
  485  ->  (   access_file(File, Mode)
  486      ->  true
  487      ;   permission_error(Mode, file, File)
  488      )
  489  ;   existence_error(file, File)
  490  ).
 file_name(+File:atom, +Name:atom) is semidet
file_name(+File:atom, -Name:atom) is det
  497file_name(File, Name) :-
  498  file_name_extensions(File, Name, _).
 file_name_extension2(+File:atom, -Name:atom, -Extension:atom) is det
file_name_extension2(-File:atom, +Name:atom, +Extension:atom) is det
  505file_name_extension2(File, Name, Ext) :-
  506  file_name_extensions(File, Name, [Ext]).
 file_name_extensions(+File:atom, -Name:atom, -Extensions:list(atom)) is det
file_name_extensions(-File:atom, +Name:atom, +Extensions:list(atom)) is det
  513file_name_extensions(File, Name, Exts) :-
  514  ground(File), !,
  515  directory_file_path2(Dir, Local, File),
  516  atomic_list_concat([Base|Exts], ., Local),
  517  directory_file_path2(Dir, Base, Name).
  518file_name_extensions(File, Name, Exts) :-
  519  atomic_list_concat([Name|Exts], ., File).
 file_size(+File:atom, -Size:nonneg) is det
See also
- Wrapper around size_file/2.
  527file_size(File, Size) :-
  528  size_file(File, Size).
 file_to_string(+File:atom, -String:string) is det
  534file_to_string(File, String) :-
  535  read_file_to_string(File, Codes, []),
  536  string_codes(String, Codes).
 guess_file_encoding(+File:atom, +Encoding:atom) is det
guess_file_encoding(+File:atom, -Encoding:atom) is det
When Encoding is instantiated to an encoding different from the guessed encoding, the error unexpected_encoding/2 is thrown.
See also
- guess_encoding/2.
  548guess_file_encoding(File, Enc1) :-
  549  read_from_file(
  550    File,
  551    {Enc2}/[In0]>>guess_encoding(In0, Enc2),
  552    options{type: binary}
  553  ),
  554  (   var(Enc1)
  555  ->  Enc1 = Enc2
  556  ;   stream_ext:clean_encoding_(Enc1, Enc3),
  557      Enc3 == Enc2
  558  ->  true
  559  ;   throw(error(unexpected_encoding(Enc2,Enc1),guess_file_encoding/2))
  560  ).
 home_directory(+Directory:atom) is semidet
home_directory(-Directory:atom) is nondet
  567home_directory(Dir) :-
  568  expand_file_name(~, [Dir]).
 is_dummy_file(+File:atom) is semidet
  574is_dummy_file(.).
  575is_dummy_file(..).
 is_empty_directory(+Directory:atom) is semidet
  581is_empty_directory(Dir) :-
  582  exists_directory(Dir),
  583  \+ directory_file(Dir, _).
 is_empty_file(+File:atom) is semidet
  589is_empty_file(File) :-
  590  read_from_file(File, at_end_of_stream).
 peek_file(+File:atom, +Size:nonneg, -String:string) is det
  596peek_file(File, Size, Str) :-
  597  read_from_file(File, {Size,Str}/[In0]>>peek_string(In0, Size, Str)).
 read_from_file(+File:atom, :Goal_1) is det
 read_from_file(+File:atom, :Goal_1, +Options:options) is det
Calls Goal_1 on the input stream derived from the given File. If the filen name ends in `.gz', GNU zip decompression is applied.
  607read_from_file(File, Goal_1) :-
  608  read_from_file(File, Goal_1, options{}).
  609
  610
  611read_from_file(File, Goal_1, Options) :-
  612  call_file_(File, read, Goal_1, Options).
 read_write_file(+File:atom, :Goal_2) is det
 read_write_file(+File:atom, :Goal_2, +ReadOptions:options, +WriteOptions:options) is det
  619read_write_file(File, Goal_2) :-
  620  read_write_file(File, Goal_2, options{}).
  621
  622
  623read_write_file(File, Goal_2, Options) :-
  624  read_write_file(File, Goal_2, Options, Options).
  625
  626
  627read_write_file(File, Goal_2, ReadOptions, WriteOptions) :-
  628  file_name_extensions(File, Base, FromExts),
  629  (   append(Exts, [gz], FromExts)
  630  ->  append(Exts, [tmp,gz], TmpExts),
  631      file_name_extensions(TmpFile, Base, TmpExts)
  632  ;   file_name_extension(File, tmp, TmpFile)
  633  ),
  634  read_write_files(File, TmpFile, Goal_2, ReadOptions, WriteOptions),
  635  rename_file(TmpFile, File).
 read_write_files(+FromFile:atom, +ToFile:atom, :Goal_2) is det
 read_write_files(+FromFile:atom, +ToFile:atom, :Goal_2, +Options:options) is det
 read_write_files(+FromFile:atom, +ToFile:atom, :Goal_2, +ReadOptions:options, +WriteOptions:options) is det
  643read_write_files(FromFile, ToFile, Goal_2) :-
  644  read_write_files(FromFile, ToFile, Goal_2, options{}).
  645
  646
  647read_write_files(FromFile, ToFile, Goal_2, Options) :-
  648  read_write_files(FromFile, ToFile, Goal_2, Options, Options).
  649
  650
  651read_write_files(FromFile, ToFile, Goal_2, ReadOptions, WriteOptions) :-
  652  create_file_directory(ToFile),
  653  call_files_(FromFile, read, ToFile, write, Goal_2, ReadOptions, WriteOptions).
 recode_file(+FromFile:atom) is det
 recode_file(+FromFile:atom, +FromEncoding:atom) is det
Recodes the given File from the given FromEncoding to UTF-8.
  662recode_file(File) :-
  663  guess_file_encoding(File, Enc),
  664  recode_file(File, Enc).
  665
  666
  667% Optimization: do not copy stream contents when the encoding remains
  668% the same.
  669recode_file(_, utf8) :- !.
  670recode_file(File, Enc) :-
  671  read_write_file(
  672    File,
  673    {Enc}/[In,Out0]>>recode_stream(In, Enc, Out0),
  674    options{type: binary}
  675  ).
 recode_files(+FromFile:atom, +ToFile:atom) is det
 recode_files(+FromFile:atom, +FromEncoding:atom, +ToFile:atom) is det
  682recode_files(FromFile, ToFile) :-
  683  guess_file_encoding(FromFile, Enc),
  684  recode_files(FromFile, Enc, ToFile).
  685
  686
  687recode_files(FromFile, Enc1, ToFile) :-
  688  stream_ext:clean_encoding_(Enc1, Enc2),
  689  (   % Optimization: do not copy stream contents when the encoding
  690      % remains the same.
  691      Enc2 == utf8
  692  ->  true
  693  ;   read_write_files(
  694        FromFile,
  695        ToFile,
  696        {Enc2}/[In0,Out0]>>recode_stream(In0, Enc2, Out0),
  697        options{type: binary}
  698      )
  699  ).
 resolve_subdirectories(+Subdirectories1:list(atom), -Subdirectories2:list(atom)) is det
Resolves `.' and `..'.
  707resolve_subdirectories([], []) :- !.
  708resolve_subdirectories([''], []) :- !.
  709resolve_subdirectories([.|T1], T2) :- !,
  710  resolve_subdirectories(T1, T2).
  711resolve_subdirectories([_,..|T1], T2) :- !,
  712  resolve_subdirectories(T1, T2).
  713resolve_subdirectories([H|T1], [H|T2]) :-
  714  resolve_subdirectories(T1, T2).
 sort_file(+File:atom) is det
 sort_file(+File:atom, +Options:options) is det
  721sort_file(File) :-
  722  sort_file(File, options{}).
  723
  724
  725sort_file(File, Options) :-
  726  read_write_file(
  727    File,
  728    {Options}/[In0,Out0]>>(
  729      sort_stream(In0, ProcOut, Options),
  730      call_cleanup(
  731        copy_stream_data(ProcOut, Out0),
  732        close(ProcOut)
  733      )
  734    )
  735  ).
 touch(+File) is det
  741touch(File) :-
  742  setup_call_cleanup(
  743    open(File, write, Out),
  744    true,
  745    close(Out)
  746  ).
 working_directory(-Directory:atom) is det
  752working_directory(Directory) :-
  753  working_directory(Directory, Directory).
 write_to_file(+File:atom, :Goal_1) is det
 write_to_file(+File:atom, :Goal_1, +Options:options) is det
If File's directory does not exist it is created.
  762write_to_file(File, Goal_1) :-
  763  write_to_file(File, Goal_1, options{}).
  764
  765
  766write_to_file(File, Goal_1, Options) :-
  767  create_file_directory(File),
  768  call_file_(File, write, Goal_1, Options).
  769
  770
  771
  772
  773
  774% GENERICS %
 call_file_(+File:atom, +DefaultMode:oneof([append,read,write]), :Goal_1, +Options:options) is det
Arguments:
Options- The following options are supported:
  • mode(+oneof([append,read,write]) Overrules the default mode.
  787call_file_(File, DefaultMode, Goal_1, Options) :-
  788  dict_get(mode, Options, DefaultMode, Mode),
  789  setup_call_cleanup(
  790    open_file_(File, Mode, Stream, Options),
  791    call(Goal_1, Stream),
  792    close(Stream)
  793  ).
 call_files_(+File1:atom, +Mode1:oneof([append,read,write]), +File2:atom, +Mode2:oneof([append,read,write]), :Goal_2, +Options1:options, +Options2:options) is det
  805call_files_(File1, Mode1, File2, Mode2, Goal_2, Options1, Options2) :-
  806  setup_call_cleanup(
  807    maplist(
  808      open_file_,
  809      [File1,File2],
  810      [Mode1,Mode2],
  811      [Stream1,Stream2],
  812      [Options1,Options2]
  813    ),
  814    call(Goal_2, Stream1, Stream2),
  815    maplist(close, [Stream1,Stream2])
  816  ).
 from_to_file_(+FromFile:atom, +Extensions:list(atom), +ToFile:atom) is semidet
from_to_file_(+FromFile:atom, +Extensions:list(atom), -ToFile:atom) is det
  823from_to_file_(FromFile, Exts, ToFile) :-
  824  var(ToFile), !,
  825  directory_file_path2(Dir, FromBase, FromFile),
  826  file_name(FromBase, Local),
  827  file_name_extensions(ToBase, Local, Exts),
  828  directory_file_path2(Dir, ToBase, ToFile).
  829from_to_file_(_, _, _).
 open_file_(+File:atom, +Mode:oneof([append,read,write]), -Stream:stream, +Options:options) is det
  838open_file_(File, Mode, Stream2, Options) :-
  839  access_file(File, Mode),
  840  open_gz_(File, Mode, Stream1, Options),
  841  open_hash_(Stream1, Stream2, Options).
 open_gz_(+File:atom, +Mode:oneof([append,read,write]), -Stream:stream, +Options:options) is det
Arguments:
Options- The following options are supported:
  • compression(+oneof([gzip,none]))
  854% explicitly no compression
  855open_gz_(File, Mode, Stream, Options) :-
  856  options{compression: none} :< Options, !,
  857  open(File, Mode, Stream, Options).
  858% compression (GNU zip)
  859open_gz_(File, Mode, Stream, Options) :-
  860  (   options{compression: gzip} :< Options
  861  ;   file_name_extension(_, gz, File)
  862  ), !,
  863  dict_terms(Options, SwiOptions),
  864  gzopen(File, Mode, Stream, SwiOptions).
  865% implicitly no compression
  866open_gz_(File, Mode, Stream, Options) :-
  867  dict_terms(Options, SwiOptions),
  868  open(File, Mode, Stream, SwiOptions).
 open_hash_(+Stream1:stream, -Stream2:stream, +Options:options) is semidet
  874open_hash_(Stream1, Stream2, Options) :-
  875  hash_algorithm_(Options, Algorithm), !,
  876  open_hash_stream(Stream1, Stream2, [algorithm(Algorithm),close_parent(false)]).
  877open_hash_(Stream, Stream, _).
  878
  879hash_algorithm_(Options, Algorithm) :-
  880  hash_algorithm(Algorithm),
  881  dict_key(Options, Algorithm)