如何检查路径是否是 C# 文件?

How to check is a path is a file with C#?

这是一个看似简单的问题,但我还没有找到满意的解决方案。

let f = FileInfo(e)
let fileFlag = f.Attributes.HasFlag(FileAttributes.Normal)
logger <| sprintf "%s :: %A :: %A" e fileFlag f.Attributes

这会产生以下输出:

/tmp/com.apple.launchd.qq7qSI6dyD/Listeners :: true :: Normal

令我惊讶的是路径是一个套接字:

> file /tmp/com.apple.launchd.qq7qSI6dyD/Listeners
/tmp/com.apple.launchd.qq7qSI6dyD/Listeners: socket

根据 FileAttributes Enum 文档:

Normal 128

The file is a standard file that has no special attributes. This attribute is valid only if it is used alone. Normal is supported on Windows, Linux, and macOS.

有没有办法检查路径是否真的是普通文件(不是套接字,不是符号链接,不是设备等)。

例如 Python:

> python -c "import os; import sys; print(os.path.isfile(sys.argv[1]))"
/tmp/com.apple.launchd.qq7qSI6dyD/Listeners
False

详细说明:

> stat -f "%N: %HT%SY" /tmp/**/*
/tmp/b: Symbolic Link -> a
/tmp/com.apple.launchd.qq7qSI6dyD: Directory
/tmp/com.apple.launchd.qq7qSI6dyD/Listeners: Socket
/tmp/fseventsd-uuid: Regular File
/tmp/powerlog: Directory
/tmp/test: Regular File
/tmp/tmux-501: Directory
/tmp/tmux-501/default: Socket

截至今天 (2021.12.16),.net 无法识别 POSIX 意义上的文件。

解决方法是按以下方式使用 Mono.Unix:

open Mono.Unix

let fileStat =
    UnixFileSystemInfo.GetFileSystemEntry(pathEntry)

let isRegular = fileStat.IsRegularFile