1 USING: help.markup help.syntax io strings
2 io.backend io.files.private quotations ;
5 ARTICLE: "file-streams" "Reading and writing files"
7 { $subsection <file-reader> }
8 { $subsection <file-writer> }
9 { $subsection <file-appender> }
10 "Reading and writing the entire contents of a file; this is only recommended for smaller files:"
11 { $subsection file-contents }
12 { $subsection set-file-contents }
13 { $subsection file-lines }
14 { $subsection set-file-lines }
15 "Utility combinators:"
16 { $subsection with-file-reader }
17 { $subsection with-file-writer }
18 { $subsection with-file-appender } ;
20 ARTICLE: "pathnames" "Pathname manipulation"
21 "Pathname manipulation:"
22 { $subsection parent-directory }
23 { $subsection file-name }
24 { $subsection last-path-separator }
25 { $subsection append-path }
26 "Pathnames relative to Factor's temporary files directory:"
27 { $subsection temp-directory }
28 { $subsection temp-file }
29 "Pathname presentations:"
30 { $subsection pathname }
31 { $subsection <pathname> } ;
33 ARTICLE: "symbolic-links" "Symbolic links"
34 "Reading and creating links:"
35 { $subsection read-link }
36 { $subsection make-link }
38 { $subsection copy-link }
39 "Not all operating systems support symbolic links."
40 { $see-also link-info } ;
42 ARTICLE: "current-directory" "Current working directory"
43 "File system I/O operations use the value of a variable to resolve relative pathnames:"
44 { $subsection current-directory }
45 "This variable can be changed with a pair of words:"
46 { $subsection set-current-directory }
47 { $subsection with-directory }
48 "This variable is independent of the operating system notion of ``current working directory''. While all Factor I/O operations use the variable and not the operating system's value, care must be taken when making FFI calls which expect a pathname. The first option is to resolve relative paths:"
49 { $subsection (normalize-path) }
50 "The second is to change the working directory of the current process:"
54 ARTICLE: "directories" "Directories"
58 { $subsection directory }
59 { $subsection directory* }
60 "Creating directories:"
61 { $subsection make-directory }
62 { $subsection make-directories }
63 { $subsection "current-directory" } ;
65 ARTICLE: "file-types" "File Types"
66 "Platform-independent types:"
67 { $subsection +regular-file+ }
68 { $subsection +directory+ }
69 "Platform-specific types:"
70 { $subsection +character-device+ }
71 { $subsection +block-device+ }
72 { $subsection +fifo+ }
73 { $subsection +symbolic-link+ }
74 { $subsection +socket+ }
75 { $subsection +unknown+ } ;
77 ARTICLE: "fs-meta" "File metadata"
78 "Querying file-system metadata:"
79 { $subsection file-info }
80 { $subsection link-info }
81 { $subsection exists? }
82 { $subsection directory? }
84 { $subsection "file-types" } ;
86 ARTICLE: "delete-move-copy" "Deleting, moving, copying files"
87 "Operations for deleting and copying files come in two forms:"
89 { "Words named " { $snippet { $emphasis "operation" } "-file" } " which work on regular files only." }
90 { "Words named " { $snippet { $emphasis "operation" } "-tree" } " works on directory trees recursively, and also accepts regular files." }
92 "The operations for moving and copying files come in three flavors:"
94 { "A word named " { $snippet { $emphasis "operation" } } " which takes a source and destination path." }
95 { "A word named " { $snippet { $emphasis "operation" } "-into" } " which takes a source path and destination directory. The destination file will be stored in the destination directory and will have the same file name as the source path." }
96 { "A word named " { $snippet { $emphasis "operation" } "s-into" } " which takes a sequence of source paths and destination directory." }
98 "Since both of the above lists apply to copying files, that this means that there are a total of six variations on copying a file."
101 { $subsection delete-file }
102 { $subsection delete-directory }
103 { $subsection delete-tree }
105 { $subsection move-file }
106 { $subsection move-file-into }
107 { $subsection move-files-into }
109 { $subsection copy-file }
110 { $subsection copy-file-into }
111 { $subsection copy-files-into }
112 "Copying directory trees recursively:"
113 { $subsection copy-tree }
114 { $subsection copy-tree-into }
115 { $subsection copy-trees-into }
116 "On most operating systems, files can only be moved within the same file system. To move files between file systems, use " { $link copy-file } " followed by " { $link delete-file } " on the old name." ;
118 ARTICLE: "io.files" "Basic file operations"
119 "The " { $vocab-link "io.files" } " vocabulary provides basic support for working with files."
120 { $subsection "pathnames" }
121 { $subsection "file-streams" }
122 { $subsection "fs-meta" }
123 { $subsection "directories" }
124 { $subsection "delete-move-copy" }
125 { $subsection "symbolic-links" } ;
129 HELP: path-separator?
130 { $values { "ch" "a code point" } { "?" "a boolean" } }
131 { $description "Tests if the code point is a platform-specific path separator." }
134 { $example "USING: io.files prettyprint ;" "CHAR: / path-separator? ." "t" }
137 HELP: parent-directory
138 { $values { "path" "a pathname string" } { "parent" "a pathname string" } }
139 { $description "Strips the last component off a pathname." }
140 { $examples { $example "USING: io io.files ;" "\"/etc/passwd\" parent-directory print" "/etc/" } } ;
143 { $values { "path" "a pathname string" } { "string" string } }
144 { $description "Outputs the last component of a pathname string." }
146 { $example "USING: io.files prettyprint ;" "\"/usr/bin/gcc\" file-name ." "\"gcc\"" }
147 { $example "USING: io.files prettyprint ;" "\"/usr/libexec/awk/\" file-name ." "\"awk\"" }
150 ! need a $class-description file-info
153 { $values { "path" "a pathname string" } { "info" file-info } }
154 { $description "Queries the file system for metadata. If " { $snippet "path" } " refers to a symbolic link, it is followed. See the article " { $link "file-types" } " for a list of metadata symbols." }
155 { $errors "Throws an error if the file does not exist." } ;
158 { $values { "path" "a pathname string" } { "info" "a file-info tuple" } }
159 { $description "Queries the file system for metadata. If path refers to a symbolic link, information about the symbolic link itself is returned. If the file does not exist, an exception is thrown." } ;
161 { file-info link-info } related-words
164 { $description "A regular file. This type exists on all platforms. See " { $link "file-streams" } " for words operating on files." } ;
167 { $description "A directory. This type exists on all platforms. See " { $link "directories" } " for words operating on directories." } ;
169 HELP: +symbolic-link+
170 { $description "A symbolic link file. This type is currently implemented on Unix platforms only. See " { $link "symbolic-links" } " for words operating on symbolic links." } ;
172 HELP: +character-device+
173 { $description "A Unix character device file. This type exists on Unix platforms only." } ;
176 { $description "A Unix block device file. This type exists on Unix platforms only." } ;
179 { $description "A Unix fifo file. This type exists on Unix platforms only." } ;
182 { $description "A Unix socket file. This type exists on Unix platforms only." } ;
185 { $description "A unknown file type." } ;
190 { "path" "a pathname string" }
191 { "encoding" "an encoding descriptor" }
192 { "stream" "an input stream" }
194 { $description "Outputs an input stream for reading from the specified pathname using the given encoding." }
195 { $errors "Throws an error if the file is unreadable." } ;
198 { $values { "path" "a pathname string" } { "encoding" "an encoding descriptor" } { "stream" "an output stream" } }
199 { $description "Outputs an output stream for writing to the specified pathname using the given encoding. The file's length is truncated to zero." }
200 { $errors "Throws an error if the file cannot be opened for writing." } ;
202 HELP: <file-appender>
203 { $values { "path" "a pathname string" } { "encoding" "an encoding descriptor" } { "stream" "an output stream" } }
204 { $description "Outputs an output stream for writing to the specified pathname using the given encoding. The stream begins writing at the end of the file." }
205 { $errors "Throws an error if the file cannot be opened for writing." } ;
207 HELP: with-file-reader
208 { $values { "path" "a pathname string" } { "encoding" "an encoding descriptor" } { "quot" "a quotation" } }
209 { $description "Opens a file for reading and calls the quotation using " { $link with-input-stream } "." }
210 { $errors "Throws an error if the file is unreadable." } ;
212 HELP: with-file-writer
213 { $values { "path" "a pathname string" } { "encoding" "an encoding descriptor" } { "quot" "a quotation" } }
214 { $description "Opens a file for writing using the given encoding and calls the quotation using " { $link with-output-stream } "." }
215 { $errors "Throws an error if the file cannot be opened for writing." } ;
217 HELP: with-file-appender
218 { $values { "path" "a pathname string" } { "encoding" "an encoding descriptor" } { "quot" "a quotation" } }
219 { $description "Opens a file for appending using the given encoding and calls the quotation using " { $link with-output-stream } "." }
220 { $errors "Throws an error if the file cannot be opened for writing." } ;
223 { $values { "seq" "an array of strings" } { "path" "a pathname string" } { "encoding" "an encoding descriptor" } }
224 { $description "Sets the contents of a file to the strings with the given encoding." }
225 { $errors "Throws an error if the file cannot be opened for writing." } ;
228 { $values { "path" "a pathname string" } { "encoding" "an encoding descriptor" } { "seq" "an array of strings" } }
229 { $description "Opens the file at the given path using the given encoding, and returns a list of the lines in that file." }
230 { $errors "Throws an error if the file cannot be opened for reading." } ;
232 HELP: set-file-contents
233 { $values { "str" "a string" } { "path" "a pathname string" } { "encoding" "an encoding descriptor" } }
234 { $description "Sets the contents of a file to a string with the given encoding." }
235 { $errors "Throws an error if the file cannot be opened for writing." } ;
238 { $values { "path" "a pathname string" } { "encoding" "an encoding descriptor" } { "str" "a string" } }
239 { $description "Opens the file at the given path using the given encoding, and the contents of that file as a string." }
240 { $errors "Throws an error if the file cannot be opened for reading." } ;
242 { set-file-lines file-lines set-file-contents file-contents } related-words
245 { $values { "path" "a pathname string" } }
246 { $description "Outputs the current working directory of the Factor process." }
247 { $errors "Windows CE has no concept of ``current directory'', so this word throws an error there." }
248 { $notes "User code should use " { $link with-directory } " or " { $link set-current-directory } " instead." } ;
251 { $values { "path" "a pathname string" } }
252 { $description "Changes the current working directory of the Factor process." }
253 { $errors "Windows CE has no concept of ``current directory'', so this word throws an error there." }
254 { $notes "User code should use " { $link with-directory } " or " { $link set-current-directory } " instead." } ;
256 { cd cwd current-directory set-current-directory with-directory } related-words
258 HELP: current-directory
259 { $description "A variable holding the current directory as an absolute path. Words that use the filesystem do so in relation to this variable."
261 "This variable should never be set directly; instead, use " { $link set-current-directory } " or " { $link with-directory } ". This preserves the invariant that the value of this variable is an absolute path." } ;
263 HELP: set-current-directory
264 { $values { "path" "a pathname string" } }
265 { $description "Changes the " { $link current-directory } " variable."
267 "If " { $snippet "path" } " is relative, it is first resolved relative to the current directory. If " { $snippet "path" } " is absolute, it becomes the new current directory." } ;
270 { $values { "path" "a pathname string" } { "quot" quotation } }
271 { $description "Calls the quotation in a new dynamic scope with the " { $link current-directory } " variable rebound."
273 "If " { $snippet "path" } " is relative, it is first resolved relative to the current directory. If " { $snippet "path" } " is absolute, it becomes the new current directory." } ;
276 { $values { "str1" "a string" } { "str2" "a string" } { "str" "a string" } }
277 { $description "Appends " { $snippet "str1" } " and " { $snippet "str2" } " to form a pathname." } ;
280 { $values { "str1" "a string" } { "str2" "a string" } { "str" "a string" } }
281 { $description "Appends " { $snippet "str2" } " and " { $snippet "str1" } " to form a pathname." } ;
283 { append-path prepend-path } related-words
286 { $values { "path" "a pathname string" } { "?" "a boolean" } }
287 { $description "Tests if a pathname is absolute. Examples of absolute pathnames are " { $snippet "/foo/bar" } " on Unix and " { $snippet "c:\\foo\\bar" } " on Windows." } ;
289 HELP: windows-absolute-path?
290 { $values { "path" "a pathname string" } { "?" "a boolean" } }
291 { $description "Tests if a pathname is absolute on Windows. Examples of absolute pathnames on Windows are " { $snippet "c:\\foo\\bar" } " and " { $snippet "\\\\?\\c:\\foo\\bar" } " for absolute Unicode pathnames." } ;
293 HELP: root-directory?
294 { $values { "path" "a pathname string" } { "?" "a boolean" } }
295 { $description "Tests if a pathname is a root directory. Examples of root directory pathnames are " { $snippet "/" } " on Unix and " { $snippet "c:\\" } " on Windows." } ;
297 { absolute-path? windows-absolute-path? root-directory? } related-words
300 { $values { "path" "a pathname string" } { "?" "a boolean" } }
301 { $description "Tests if the file named by " { $snippet "path" } " exists." } ;
304 { $values { "file-info" file-info } { "?" "a boolean" } }
305 { $description "Tests if " { $snippet "file-info" } " is a directory." } ;
308 { $values { "path" "a pathname string" } { "seq" "a sequence of " { $snippet "{ name dir? }" } " pairs" } }
309 { $description "Outputs the contents of a directory named by " { $snippet "path" } "." }
310 { $notes "This is a low-level word, and user code should call " { $link directory } " instead." } ;
313 { $values { "path" "a pathname string" } { "seq" "a sequence of " { $snippet "{ name dir? }" } " pairs" } }
314 { $description "Outputs the contents of a directory named by " { $snippet "path" } "." } ;
317 { $values { "path" "a pathname string" } { "seq" "a sequence of " { $snippet "{ path dir? }" } " pairs" } }
318 { $description "Outputs the contents of a directory named by " { $snippet "path" } "." }
319 { $notes "Unlike " { $link directory } ", this word prepends the directory's path to all file names in the list." } ;
321 ! HELP: file-modified
322 ! { $values { "path" "a pathname string" } { "n" "a non-negative integer or " { $link f } } }
323 ! { $description "Outputs a file's last modification time, since midnight January 1, 1970. If the file does not exist, outputs " { $link f } "." } ;
326 { $values { "path" "a pathname string" } { "newpath" "a pathname string" } }
327 { $description "Resolve a path relative to the Factor source code location." } ;
330 { $class-description "Class of path name objects. Path name objects can be created by calling " { $link <pathname> } "." } ;
332 HELP: normalize-directory
333 { $values { "str" "a pathname string" } { "newstr" "a new pathname string" } }
334 { $description "Called by the " { $link directory } " word to prepare a pathname before passing it to the " { $link (directory) } " primitive." } ;
337 { $values { "str" "a pathname string" } { "newstr" "a new pathname string" } }
338 { $description "Called by words such as " { $link <file-reader> } " and " { $link <file-writer> } " to prepare a pathname before passing it to underlying code." } ;
340 HELP: <pathname> ( str -- pathname )
341 { $values { "str" "a pathname string" } { "pathname" pathname } }
342 { $description "Creates a new " { $link pathname } "." } ;
345 { $values { "target" "a path to the symbolic link's target" } { "symlink" "a path to new symbolic link" } }
346 { $description "Creates a symbolic link." } ;
349 { $values { "symlink" "a path to an existing symbolic link" } { "path" "the path pointed to by the symbolic link" } }
350 { $description "Reads the symbolic link and returns its target path." } ;
353 { $values { "target" "a path to an existing symlink" } { "symlink" "a path to a new symbolic link" } }
354 { $description "Copies a symbolic link without following the link." } ;
356 { make-link read-link copy-link } related-words
359 { $values { "dir" string } }
360 { $description "Outputs the user's home directory." } ;
363 { $values { "path" "a pathname string" } }
364 { $description "Deletes a file." }
365 { $errors "Throws an error if the file could not be deleted." } ;
368 { $values { "path" "a pathname string" } }
369 { $description "Creates a directory." }
370 { $errors "Throws an error if the directory could not be created." } ;
372 HELP: make-directories
373 { $values { "path" "a pathname string" } }
374 { $description "Creates a directory and any parent directories which do not yet exist." }
375 { $errors "Throws an error if the directories could not be created." } ;
377 HELP: delete-directory
378 { $values { "path" "a pathname string" } }
379 { $description "Deletes a directory. The directory must be empty." }
380 { $errors "Throws an error if the directory could not be deleted." } ;
383 { $values { "path" "a pathname string" } }
384 { $description "Updates the modification time of a file or directory. If the file does not exist, creates a new, empty file." }
385 { $errors "Throws an error if the file could not be touched." } ;
388 { $values { "path" "a pathname string" } }
389 { $description "Deletes a file or directory, recursing into subdirectories." }
390 { $errors "Throws an error if the deletion fails." }
391 { $warning "Misuse of this word can lead to catastrophic data loss." } ;
394 { $values { "from" "a pathname string" } { "to" "a pathname string" } }
395 { $description "Moves or renames a file." }
396 { $errors "Throws an error if the file does not exist or if the move operation fails." } ;
399 { $values { "from" "a pathname string" } { "to" "a directory pathname string" } }
400 { $description "Moves a file to another directory without renaming it." }
401 { $errors "Throws an error if the file does not exist or if the move operation fails." } ;
403 HELP: move-files-into
404 { $values { "files" "a sequence of pathname strings" } { "to" "a directory pathname string" } }
405 { $description "Moves a set of files to another directory." }
406 { $errors "Throws an error if the file does not exist or if the move operation fails." } ;
409 { $values { "from" "a pathname string" } { "to" "a pathname string" } }
410 { $description "Copies a file." }
411 { $notes "This operation attempts to preserve the original file's attributes, however not all attributes may be preserved." }
412 { $errors "Throws an error if the file does not exist or if the copy operation fails." } ;
415 { $values { "from" "a pathname string" } { "to" "a directory pathname string" } }
416 { $description "Copies a file to another directory." }
417 { $errors "Throws an error if the file does not exist or if the copy operation fails." } ;
419 HELP: copy-files-into
420 { $values { "files" "a sequence of pathname strings" } { "to" "a directory pathname string" } }
421 { $description "Copies a set of files to another directory." }
422 { $errors "Throws an error if the file does not exist or if the copy operation fails." } ;
425 { $values { "from" "a pathname string" } { "to" "a pathname string" } }
426 { $description "Copies a directory tree recursively." }
427 { $notes "This operation attempts to preserve original file attributes, however not all attributes may be preserved." }
428 { $errors "Throws an error if the copy operation fails." } ;
431 { $values { "from" "a pathname string" } { "to" "a directory pathname string" } }
432 { $description "Copies a directory tree to another directory, recursively." }
433 { $errors "Throws an error if the copy operation fails." } ;
435 HELP: copy-trees-into
436 { $values { "files" "a sequence of pathname strings" } { "to" "a directory pathname string" } }
437 { $description "Copies a set of directory trees to another directory, recursively." }
438 { $errors "Throws an error if the copy operation fails." } ;