file

package
v0.20.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 14, 2022 License: Apache-2.0 Imports: 17 Imported by: 13

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var DefaultDirPerms = 0700
View Source
var DefaultPerms = 0600

DefaultPerms for new file creation.

Functions

func Cat added in v0.13.0

func Cat(path string) error

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

func Edit(path string) error

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

func Exists(path string) bool

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

func Fetch(from, to string) error

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

func Field(path string, n int) []string

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

func FindString(path, regx string) (string, error)

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(path string, n int) ([]string, error)

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

func HereOrAbove(name string) (string, error)

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

func IsEmpty(path string) bool

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

func Overwrite(path, buf string) error

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

func Replace(orig, url string) error

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

func ReplaceAllString(path, regx, repl string) error

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

func Size(path string) int64

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

func Tail(path string, n int) ([]string, error)

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

func Touch(path string) error

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

type Multipart struct {
	Delimiter string
	Map       map[string]string
}

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

func (o Multipart) MarshalText() ([]byte, error)

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

func (o Multipart) String() string

String fulfills the fmt.Stringer interface by calling MarshalText.

func (*Multipart) UnmarshalText added in v0.19.0

func (o *Multipart) UnmarshalText(text []byte) error

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

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL