Documentation
¶
Overview ¶
Package os provides OS helpers: file probes, safe writes, copy, and line I/O.
Index ¶
- func AtomicWrite(path string, data []byte, perm os.FileMode) error
- func CopyFile(src, dst string) error
- func EnsureDir(dir string, perm os.FileMode) error
- func EnsureFile(path string, perm os.FileMode) error
- func Exists(path string) (bool, error)
- func IsDir(path string) (bool, error)
- func IsExecutable(path string) (bool, error)
- func IsFile(path string) (bool, error)
- func IsSymlink(path string) (bool, error)
- func IsWritableDir(dir string) bool
- func ReadLines(path string) ([]string, error)
- func SameFile(a, b string) (bool, error)
- func Trash(path string) error
- func WriteLines(path string, lines []string, perm os.FileMode) error
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AtomicWrite ¶
AtomicWrite writes `data` to `path` via a temp-file-and-rename in the same directory. The temp file is removed on any failure.
Example ¶
package main
import (
"fmt"
"os"
"path/filepath"
xos "github.com/gechr/x/os"
)
func main() {
dir, _ := os.MkdirTemp("", "example")
defer func() { _ = os.RemoveAll(dir) }()
path := filepath.Join(dir, "config.txt")
if err := xos.AtomicWrite(path, []byte("hello\n"), 0o600); err != nil {
fmt.Println(err)
return
}
data, _ := os.ReadFile(path)
fmt.Printf("%s", data)
}
Output: hello
func CopyFile ¶
CopyFile copies `src` to `dst`, preserving `src`'s mode bits. `dst` is fsynced before close. When `src` and `dst` are the same file (including via hard link) CopyFile is a no-op.
Example ¶
package main
import (
"fmt"
"os"
"path/filepath"
xos "github.com/gechr/x/os"
)
func main() {
dir, _ := os.MkdirTemp("", "example")
defer func() { _ = os.RemoveAll(dir) }()
src := filepath.Join(dir, "src.txt")
dst := filepath.Join(dir, "dst.txt")
_ = os.WriteFile(src, []byte("hello\n"), 0o600)
if err := xos.CopyFile(src, dst); err != nil {
fmt.Println(err)
return
}
data, _ := os.ReadFile(dst)
fmt.Printf("%s", data)
}
Output: hello
func EnsureDir ¶
EnsureDir creates `dir` and any missing parents, and guarantees `dir` itself has mode `perm` even if it already existed with a different mode or the umask interfered at creation time. Pre-existing parents are left untouched.
Example ¶
EnsureDir creates missing parent directories, like mkdir -p.
package main
import (
"fmt"
"os"
"path/filepath"
xos "github.com/gechr/x/os"
)
func main() {
dir, _ := os.MkdirTemp("", "example")
defer func() { _ = os.RemoveAll(dir) }()
nested := filepath.Join(dir, "a", "b", "c")
if err := xos.EnsureDir(nested, 0o755); err != nil {
fmt.Println(err)
return
}
isDir, _ := xos.IsDir(nested)
fmt.Println(isDir)
}
Output: true
func EnsureFile ¶
EnsureFile creates `path` as an empty file with mode `perm` if it does not exist, creating any missing parent directories. An existing file's contents, mode, and timestamps are left untouched.
Example ¶
EnsureFile creates the file and any missing parent directories.
package main
import (
"fmt"
"os"
"path/filepath"
xos "github.com/gechr/x/os"
)
func main() {
dir, _ := os.MkdirTemp("", "example")
defer func() { _ = os.RemoveAll(dir) }()
path := filepath.Join(dir, "a", "b", "config.txt")
if err := xos.EnsureFile(path, 0o600); err != nil {
fmt.Println(err)
return
}
isFile, _ := xos.IsFile(path)
fmt.Println(isFile)
}
Output: true
func Exists ¶
Exists reports whether `path` exists.
Example ¶
package main
import (
"fmt"
"os"
"path/filepath"
xos "github.com/gechr/x/os"
)
func main() {
dir, _ := os.MkdirTemp("", "example")
defer func() { _ = os.RemoveAll(dir) }()
path := filepath.Join(dir, "file.txt")
_ = os.WriteFile(path, []byte("hello"), 0o600)
exists, _ := xos.Exists(path)
missing, _ := xos.Exists(filepath.Join(dir, "missing.txt"))
fmt.Println(exists)
fmt.Println(missing)
}
Output: true false
func IsDir ¶
IsDir reports whether `path` is a directory.
Example ¶
package main
import (
"fmt"
"os"
"path/filepath"
xos "github.com/gechr/x/os"
)
func main() {
dir, _ := os.MkdirTemp("", "example")
defer func() { _ = os.RemoveAll(dir) }()
path := filepath.Join(dir, "file.txt")
_ = os.WriteFile(path, []byte("hello"), 0o600)
isDir, _ := xos.IsDir(dir)
notDir, _ := xos.IsDir(path)
fmt.Println(isDir)
fmt.Println(notDir)
}
Output: true false
func IsExecutable ¶
IsExecutable reports whether `path`, with every symlink resolved, is a regular file that the current process can run as a binary. It answers the practical question rather than merely inspecting the permission bits: on Unix via `access(2)` with `X_OK` (so the owner/group/other bit that actually applies to this process is used), and on Windows via the resolved file's extension appearing in `%PATHEXT%` (Windows has no execute bit). A non-existent path reports false; a directory is traversable, not runnable, so it also reports false.
func IsFile ¶
IsFile reports whether `path` is a regular file.
Example ¶
package main
import (
"fmt"
"os"
"path/filepath"
xos "github.com/gechr/x/os"
)
func main() {
dir, _ := os.MkdirTemp("", "example")
defer func() { _ = os.RemoveAll(dir) }()
path := filepath.Join(dir, "file.txt")
_ = os.WriteFile(path, []byte("hello"), 0o600)
file, _ := xos.IsFile(path)
notFile, _ := xos.IsFile(dir)
fmt.Println(file)
fmt.Println(notFile)
}
Output: true false
func IsSymlink ¶
IsSymlink reports whether `path` is a symbolic link.
Example ¶
package main
import (
"fmt"
"os"
"path/filepath"
xos "github.com/gechr/x/os"
)
func main() {
dir, _ := os.MkdirTemp("", "example")
defer func() { _ = os.RemoveAll(dir) }()
path := filepath.Join(dir, "file.txt")
_ = os.WriteFile(path, []byte("hello"), 0o600)
link := filepath.Join(dir, "link.txt")
_ = os.Symlink(path, link)
isLink, _ := xos.IsSymlink(link)
notLink, _ := xos.IsSymlink(path)
fmt.Println(isLink)
fmt.Println(notLink)
}
Output: true false
func IsWritableDir ¶
IsWritableDir reports whether `dir` exists and the current process can create files in it. Uses a probe file rather than permission-bit inspection so that ACLs and immutable mounts are handled correctly.
Example ¶
A missing path is not a writable directory.
package main
import (
"fmt"
"os"
"path/filepath"
xos "github.com/gechr/x/os"
)
func main() {
dir, _ := os.MkdirTemp("", "example")
defer func() { _ = os.RemoveAll(dir) }()
fmt.Println(xos.IsWritableDir(dir))
fmt.Println(xos.IsWritableDir(filepath.Join(dir, "missing")))
}
Output: true false
func ReadLines ¶
ReadLines reads `path` and returns its non-empty, trimmed lines.
Example ¶
ReadLines drops blank lines and trims surrounding whitespace.
package main
import (
"fmt"
"os"
"path/filepath"
xos "github.com/gechr/x/os"
)
func main() {
dir, _ := os.MkdirTemp("", "example")
defer func() { _ = os.RemoveAll(dir) }()
path := filepath.Join(dir, "lines.txt")
_ = os.WriteFile(path, []byte(" alpha \n\n\tbeta\n\ngamma\n"), 0o600)
lines, _ := xos.ReadLines(path)
for _, line := range lines {
fmt.Println(line)
}
}
Output: alpha beta gamma
func SameFile ¶
SameFile reports whether `a` and `b` identify the same file. Missing leaf paths are compared after resolving their parent directories, and existing files are compared with os.SameFile to detect hard links.
Example ¶
package main
import (
"fmt"
"os"
"path/filepath"
xos "github.com/gechr/x/os"
)
func main() {
dir, _ := os.MkdirTemp("", "example")
defer func() { _ = os.RemoveAll(dir) }()
path := filepath.Join(dir, "file.txt")
_ = os.WriteFile(path, []byte("hello"), 0o600)
link := filepath.Join(dir, "link.txt")
_ = os.Link(path, link)
other := filepath.Join(dir, "other.txt")
_ = os.WriteFile(other, []byte("hello"), 0o600)
same, _ := xos.SameFile(path, link)
different, _ := xos.SameFile(path, other)
fmt.Println(same)
fmt.Println(different)
}
Output: true false
func Trash ¶
Trash asks the operating system to move `path` to its trash (or recycle bin) rather than removing it permanently like os.Remove, so it can typically be recovered. The `path` is resolved to an absolute path first, so a relative path trashes the intended file regardless of the working directory.
The mechanism is platform-specific: the system trash tool on macOS (so the Finder's "Put Back" works), the FreeDesktop.org trash specification on Linux and other Unix systems, and the shell file operation that targets the Recycle Bin on Windows. Recoverability is the OS's to honor, not a guarantee: an environment with the Recycle Bin disabled, for instance, may delete outright.
Where the platform cannot trash, it returns an error wrapping errors.ErrUnsupported, so a caller can detect the case and decide what to do (e.g. fall back to os.Remove). This covers a macOS older than 15 (which lacks the system trash tool) and a Unix file with no usable same-device trash.
func WriteLines ¶
WriteLines atomically writes `lines` to `path`, one per line, with a trailing newline.
Example ¶
package main
import (
"fmt"
"os"
"path/filepath"
xos "github.com/gechr/x/os"
)
func main() {
dir, _ := os.MkdirTemp("", "example")
defer func() { _ = os.RemoveAll(dir) }()
path := filepath.Join(dir, "lines.txt")
if err := xos.WriteLines(path, []string{"alpha", "beta"}, 0o600); err != nil {
fmt.Println(err)
return
}
data, _ := os.ReadFile(path)
fmt.Printf("%q\n", data)
}
Output: "alpha\nbeta\n"
Types ¶
This section is empty.