//go:build !windows && !wasm package filesystem import ( "io" "os" "path/filepath" "syscall" "github.com/xtls/xray-core/common/buf" "github.com/xtls/xray-core/common/platform" ) type FileReaderFunc func(path string) (io.ReadCloser, error) var NewFileReader FileReaderFunc = func(path string) (io.ReadCloser, error) { return os.Open(path) } func ReadFile(path string) ([]byte, error) { file, err := os.Open(path) if err != nil { return nil, err } defer file.Close() stat, err := file.Stat() if err != nil { return nil, err } size := stat.Size() if size == 0 { return []byte{}, nil } // use mmap to save RAM bs, err := syscall.Mmap(int(file.Fd()), 0, int(size), syscall.PROT_READ, syscall.MAP_SHARED) if err == nil { return bs, nil } // fallback reader, err := NewFileReader(path) if err != nil { return nil, err } defer reader.Close() return buf.ReadAllToBytes(reader) } func ReadAsset(file string) ([]byte, error) { return ReadFile(platform.GetAssetLocation(file)) } func ReadCert(file string) ([]byte, error) { if filepath.IsAbs(file) { return ReadFile(file) } return ReadFile(platform.GetCertLocation(file)) } func CopyFile(dst string, src string) error { bytes, err := ReadFile(src) if err != nil { return err } f, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY, 0o644) if err != nil { return err } defer f.Close() _, err = f.Write(bytes) return err }