Documentation ¶
Index ¶
- Variables
- func Cat(path string) error
- func Edit(path string) error
- func Exists(path string) bool
- func Fetch(from, to string) error
- func Field(path string, n int) []string
- func FindString(path, regx string) (string, error)
- func Head(path string, n int) ([]string, error)
- func HereOrAbove(name string) (string, error)
- func IsEmpty(path string) bool
- func Overwrite(path, buf string) error
- func Replace(orig, url string) error
- func ReplaceAllString(path, regx, repl string) error
- func Size(path string) int64
- func Tail(path string, n int) ([]string, error)
- func Touch(path string) error
- type Multipart
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var DefaultDirPerms = 0700
var DefaultPerms = 0600
DefaultPerms for new file creation.
Functions ¶
func Cat ¶ added in v0.13.0
Cat just prints the contents of target file to stdout. If the file cannot be found or opened returns error. For performance, the entire file is loaded into memory before being written to stdout. Do not use this on anything where the size of the file is unknown and untrusted.
func Edit ¶ added in v0.3.2
Edit opens the file at the given path for editing searching for an editor on the system using the following (in order of priority):
* VISUAL * EDITOR * code * vim * vi * emacs * nano
func Exists ¶
Exists calls fs.Exists and further confirms that the file is a file and not a directory.
Example ¶
package main import ( "fmt" "github.com/rwxrob/fs/file" ) func main() { fmt.Println(file.Exists("testdata/exists")) fmt.Println(file.Exists("testdata")) }
Output: true false
func Fetch ¶ added in v0.2.0
Fetch fetches the specified file at the give "from" URL and saves it "to" the specified file path. The name is *not* inferred. If timeouts, status, and contexts are required use the net/http package instead. Will block until the entire file is downloaded. For more involved downloading needs consider the github.com/cavaliercoder/grab package.
Example ¶
package main import ( "fmt" "net/http" ht "net/http/httptest" "os" "github.com/rwxrob/fs/file" ) func main() { // serve get handler := http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, `random file content`) }) svr := ht.NewServer(handler) defer svr.Close() defer os.Remove(`testdata/file`) // not found handler = http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(404) }) notfound := ht.NewServer(handler) defer notfound.Close() if err := file.Fetch(svr.URL, `testdata/file`); err != nil { fmt.Println(err) } it, _ := os.ReadFile(`testdata/file`) fmt.Println(string(it)) if err := file.Fetch(notfound.URL, `testdata/file`); err != nil { fmt.Println(err) } }
Output: random file content 404 Not Found
func Field ¶ added in v0.19.2
Field returns the field (as returned by strings.Fields) from each line of the file located at path (like awk '{print $1}'). Always returns a slice even if empty. If that field does not exist on a line, that line is omitted. Note that field count starts at 1 (not 0).
Example ¶
package main import ( "fmt" "github.com/rwxrob/fs/file" ) func main() { fmt.Println(file.Field(`testdata/fieldtest`, 2)) }
Output: [foo bar baz]
func FindString ¶ added in v0.12.0
FindString reads the file at path into a string, dynamically compiles the regx regular expression, and returns FindString on it returning an error if file does not exist, or if regular expression could not compile. Note that it is not an error to not find the string, which causes an empty string to be returned. See regexp.FindString.
Example ¶
package main import ( "fmt" "github.com/rwxrob/fs/file" ) func main() { str, err := file.FindString(`testdata/headtail`, `thre+`) if err != nil { fmt.Println(err) } fmt.Println(str) }
Output: three
func Head ¶ added in v0.12.0
Head is like the UNIX head command returning only that number of lines from the top of a file.
Example ¶
package main import ( "fmt" "github.com/rwxrob/fs/file" ) func main() { lines, err := file.Head(`testdata/headtail`, 2) if err != nil { fmt.Println(err) } fmt.Println(lines) }
Output: [one two]
Example (Over) ¶
package main import ( "fmt" "github.com/rwxrob/fs/file" ) func main() { lines, err := file.Head(`testdata/headtail`, 20) if err != nil { fmt.Println(err) } fmt.Println(lines) }
Output: [one two three four five]
func HereOrAbove ¶ added in v0.5.2
HereOrAbove returns the full path to the file if the file is found in the current working directory, or if not exists in any parent directory recursively.
Example (Above) ¶
package main import ( "fmt" "os" "path/filepath" "strings" "github.com/rwxrob/fs/file" ) func main() { dir, _ := os.Getwd() defer func() { os.Chdir(dir) }() os.Chdir("testdata/adir") path, err := file.HereOrAbove("anotherfile") if err != nil { fmt.Println(err) } d := strings.Split(path, string(filepath.Separator)) fmt.Println(d[len(d)-2:]) }
Output: [testdata anotherfile]
Example (Here) ¶
package main import ( "fmt" "os" "path/filepath" "strings" "github.com/rwxrob/fs/file" ) func main() { dir, _ := os.Getwd() defer func() { os.Chdir(dir) }() os.Chdir("testdata/adir") path, err := file.HereOrAbove("afile") if err != nil { fmt.Println(err) } d := strings.Split(path, string(filepath.Separator)) fmt.Println(d[len(d)-2:]) }
Output: [adir afile]
func IsEmpty ¶ added in v0.14.0
IsEmpty checks for files of zero length in an OS-agnostic way. If the file does not exist returns false.
Example ¶
package main import ( "fmt" "github.com/rwxrob/fs/file" ) func main() { fmt.Println(file.IsEmpty(`testdata/overwritten`)) fmt.Println(file.IsEmpty(`testdata/ovewritten`)) file.Touch(`testdata/emptyfile`) fmt.Println(file.IsEmpty(`testdata/emptyfile`)) }
Output: false false true
func Overwrite ¶ added in v0.12.0
Overwrite replaces the content of the target file at path with the string passed using the same file-level locking used by Go. File permissions are preserved if file exists.
Example ¶
package main import ( "fmt" "os" "github.com/rwxrob/fs/file" ) func main() { err := file.Overwrite(`testdata/overwritten`, `hello`) defer os.Remove(`testdata/overwritten`) if err != nil { fmt.Println(err) } file.Cat(`testdata/overwritten`) }
Output: hello
func Replace ¶ added in v0.2.0
Replace replaces a file at a specified location with another successfully retrieved file from the specified URL or file path and duplicates the original files permissions. Only http and https URLs are currently supported. For security reasons, no backup copy of the replaced executable is kept. Also no checksum validation of the file is performed (which is fine in most cases where the connection has been secured with HTTPS).
Example ¶
package main import ( "fmt" "net/http" ht "net/http/httptest" "os" "github.com/rwxrob/fs/file" ) func main() { // serve get handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, `something random`) }) svr := ht.NewServer(handler) defer svr.Close() // create a file to replace os.Create(`testdata/replaceme`) defer os.Remove(`testdata/replaceme`) os.Chmod(`testdata/replaceme`, 0400) // show info about control file info, err := os.Stat(`testdata/replaceme`) if err != nil { fmt.Println(err) } fmt.Println(info.Mode()) fmt.Println(info.Size()) // replace it with local url file.Replace(`testdata/replaceme`, svr.URL) // check that it is new info, err = os.Stat(`testdata/replaceme`) if err != nil { fmt.Println(err) } fmt.Println(info.Mode()) fmt.Println(info.Size()) }
Output: -r-------- 0 -r-------- 16
func ReplaceAllString ¶ added in v0.12.0
ReplaceAllString loads the file at path into buffer, compiles the regx, and replaces all matches with repl same as function of same name overwriting the target file at path. Returns and error if unable to compile the regular expression or read or overwrite the file.
Normally, it is better to pre-compile regular expressions. This function is designed for applications where the regular expression and replacement string are passed by the user at runtime.
func Size ¶ added in v0.18.0
Size returns the info.Size() of the file from os.Stat(path). Returns -1 if unable to determine.
Example ¶
package main import ( "fmt" "github.com/rwxrob/fs/file" ) func main() { fmt.Println(file.Size(`testdata/headtail`)) }
Output: 24
func Tail ¶ added in v0.12.0
Tail is like the UNIX tail command returning only that number of lines from the bottom of a file. If n is negative counts that many lines from the top of the file (effectively the line to start from).
Example ¶
package main import ( "fmt" "github.com/rwxrob/fs/file" ) func main() { lines, err := file.Tail(`testdata/headtail`, 2) if err != nil { fmt.Println(err) } fmt.Println(lines) }
Output: [four five]
Example (Negative) ¶
package main import ( "fmt" "github.com/rwxrob/fs/file" ) func main() { lines, err := file.Tail(`testdata/headtail`, -2) if err != nil { fmt.Println(err) } fmt.Println(lines) }
Output: [three four five]
Example (Over) ¶
package main import ( "fmt" "github.com/rwxrob/fs/file" ) func main() { lines, err := file.Tail(`testdata/headtail`, 20) if err != nil { fmt.Println(err) } fmt.Println(lines) }
Output: [one two three four five]
func Touch ¶
Touch creates a new file at path or updates the time stamp of existing. If a new file is needed creates it with 0600 permissions (instead of 0666 as default os.Create does). If the directory does not exist it is also created using DefaultDirPerms.
Example (Create) ¶
package main import ( "fmt" "os" "github.com/rwxrob/fs" "github.com/rwxrob/fs/file" ) func main() { fmt.Println(fs.NotExists("testdata/foo")) file.Touch("testdata/foo") fmt.Println(fs.Exists("testdata/foo")) os.Remove("testdata/foo") }
Output: true true
Example (Update) ¶
package main import ( "fmt" "log" "github.com/rwxrob/fs" "github.com/rwxrob/fs/file" ) func main() { // first create it and capture the time as a string file.Touch("testdata/tmpfile") u1 := fs.ModTime("testdata/tmpfile") log.Print(u1) // touch it and capture the new time file.Touch("testdata/tmpfile") u2 := fs.ModTime("testdata/tmpfile") log.Print(u2) // check that they are not equiv fmt.Println(u1 == u2) }
Output: false
Types ¶
type Multipart ¶ added in v0.19.0
Multipart is meant to contain the delimited sections of output and can be marshalled into a single delimited string safely and automatically simply by using it in a string context.
func (Multipart) MarshalText ¶ added in v0.19.0
MarshalText fulfills the encoding.TextMarshaler interface by delimiting each section of output with a unique delimiter line that contains a space and the key for each section. Order of sections is indeterminate officially (but consistent for testing, per Go). The special "break" delimiter is always the last line. The Delimiter is used if defined, otherwise one is automatically assigned.
func (Multipart) String ¶ added in v0.19.0
String fulfills the fmt.Stringer interface by calling MarshalText.
func (*Multipart) UnmarshalText ¶ added in v0.19.0
UnmarshalText fulfills the encoding.TextUnmarshaler interface by using its internal Delimiter or sensing the delimiter as the first text field (up to the first space) if not set and using that delimiter to parse the remaining data into the key/value pairs ending when either the end of text is encountered or the special "break" delimiter is read.
Example (Explicit) ¶
package main import ( "fmt" "github.com/rwxrob/fs/file" ) func main() { out := file.Multipart{ Delimiter: `IMMADELIM`, Map: map[string]string{`dummy`: `just checking`}, } buf := ` random ignored lines here IMMADELIM stdout some standard output on multiple lines IMMADELIM stderr some standard err on single line IMMADELIM exitval -1 IMMADELIM break ` err := out.UnmarshalText([]byte(buf)) if err != nil { fmt.Println(err) } fmt.Print(out) }
Output: IMMADELIM stdout some standard output on multiple lines IMMADELIM stderr some standard err on single line IMMADELIM exitval -1 IMMADELIM break