package nfs import ( "git.noahlan.cn/noahlan/ntool/internal/common" "git.noahlan.cn/noahlan/ntool/ncrypt" "io" "net/http" "os" "path/filepath" "strings" ) const ( // MimeSniffLen sniff Length, use for detect file mime type MimeSniffLen = 512 ) // OSTempFile create a temp file on os.TempDir() // The file is kept as open, the caller should close the file handle, and remove the file by name. // // Usage: // // nfs.OSTempFile("example.*.txt") func OSTempFile(pattern string) (*os.File, error) { return os.CreateTemp(os.TempDir(), pattern) } // OSTempFileWithContent create a temp file on os.TempDir() with the given content func OSTempFileWithContent(content string) (*os.File, error) { tmp, err := OSTempFile(ncrypt.Md5String(content)) if err != nil { return nil, err } if err = os.WriteFile(tmp.Name(), []byte(content), os.ModeTemporary); err != nil { return nil, err } return tmp, nil } // OSTempFilenameWithContent create a temp file on os.TempDir() with the given content and returns the filename (full path). // The caller should remove the file by name after use. func OSTempFilenameWithContent(content string) (string, error) { tmp, err := OSTempFileWithContent(content) if err != nil { return "", err } filename := tmp.Name() if err = tmp.Close(); err != nil { return "", err } return filename, nil } // TempFile is like os.CreateTemp, but can custom temp dir. // // Usage: // // nfs.TempFile("", "example.*.txt") func TempFile(dir, pattern string) (*os.File, error) { return os.CreateTemp(dir, pattern) } // OSTempDir creates a new temp dir on os.TempDir and return the temp dir path // // Usage: // // nfs.OSTempDir("example.*") func OSTempDir(pattern string) (string, error) { return os.MkdirTemp(os.TempDir(), pattern) } // TempDir creates a new temp dir and return the temp dir path // // Usage: // // nfs.TempDir("", "example.*") // nfs.TempDir("testdata", "example.*") func TempDir(dir, pattern string) (string, error) { return os.MkdirTemp(dir, pattern) } // MimeType get File Mime Type name. eg "image/png" func MimeType(path string) (mime string) { file, err := os.Open(path) if err != nil { return } return ReaderMimeType(file) } // ReaderMimeType get the io.Reader mimeType // // Usage: // // file, err := os.Open(filepath) // if err != nil { // return // } // mime := ReaderMimeType(file) func ReaderMimeType(r io.Reader) (mime string) { var buf [MimeSniffLen]byte n, _ := io.ReadFull(r, buf[:]) if n == 0 { return "" } return http.DetectContentType(buf[:n]) } // JoinPaths elements, alias of filepath.Join() func JoinPaths(elem ...string) string { return filepath.Join(elem...) } // JoinSubPaths elements, like the filepath.Join() func JoinSubPaths(basePath string, elem ...string) string { paths := make([]string, len(elem)+1) paths[0] = basePath copy(paths[1:], elem) return filepath.Join(paths...) } // SlashPath alias of filepath.ToSlash func SlashPath(path string) string { return filepath.ToSlash(path) } // UnixPath like of filepath.ToSlash, but always replace func UnixPath(path string) string { if !strings.ContainsRune(path, '\\') { return path } return strings.ReplaceAll(path, "\\", "/") } // ToAbsPath convert process. will expand home dir // // TIP: will don't check path func ToAbsPath(p string) string { if len(p) == 0 || IsAbsPath(p) { return p } // expand home dir if p[0] == '~' { return common.ExpandHome(p) } wd, err := os.Getwd() if err != nil { return p } return filepath.Join(wd, p) }