我是 powershell 新手,我想检查文件是否可读且正常。在 unix 中,我们可以使用 -f 和 -r 在一行中完成此操作。例如,以下 shell 脚本函数接受文件名作为参数并检查文件的可读性和规律性,与此等效的 powershell 是什么?
_ChkRegularFile_R() # checks whether a file is regular and readable
{
_CRFRfilename=$1 # name of the file to be checked
_CRFRsts=1 # default is error
if [ -f "$_CRFRfilename" ]
then
if [ -r "$_CRFRfilename" ]
then
_CRFRsts=0 # success: regular file is readable
fi
fi
return $_CRFRsts
}
最佳答案
要测试文件是否可读,您可以尝试打开它。如果出现错误,则该文件不可读。您需要根据需要捕获或捕获异常或因错误而停止。请记住,Windows 会锁定打开以进行写入的文件,因此应用程序需要预料到它们有时无法打开文件。
如果确实有必要,您可以使用类似的方法来测试是否可以读取文件:
try {
[System.IO.File]::OpenRead($FullPathName).Close()
$Readable = $true
}
catch {
$Readable = $false
}
这是为了测试您是否可以写入文件:
try {
[System.IO.File]::OpenWrite($FullPathName).Close()
$Writable = $true
}
catch {
$Writable = $false
}
如果您确实需要的话,该逻辑很容易包装到函数中。
就文件类型而言,Windows 文件系统中的几乎所有内容都是普通文件或目录,因为 Windows 没有“一切都是文件”约定。所以,通常你可以按如下方式进行测试:
# Test if file-like
Test-Path -Path $Path -Leaf
# Test if directory-like
Test-Path -Path $Path -Container
如果您正在使用 FileInfo
或 DirectoryInfo
对象(即 Get-Item
的输出,Get- ChildItem
,或代表文件或目录的类似对象),您将拥有 PSIsContainer
属性,该属性将告诉您该项目是文件还是目录。
这可能涵盖了 99.999% 的情况。
但是,如果您需要知道某个文件是否是 NTFS 硬链接(hard link)(罕见,但最古老),则 NTFS junction to a directory ,一个NTFS symlink ,一个NTFS volume mount point ,或any type of NTFS reparse point ,事情变得更加复杂。 [This answer很好地描述了前三个。]
让我们创建一个简单的 NTFS 文件夹来测试:
# Create a test directory and change to it.
New-Item -Path C:\linktest -ItemType Directory | Select-Object -ExpandProperty FullName | Push-Location
# Create an empty file
New-Item -Path .\file1 -ItemType file -Value $null | Out-Null
New-Item -Path .\file2 -ItemType file -Value $null | Out-Null
# Create a directory
New-Item -Path .\dir1 -ItemType Directory | Out-Null
# Create a symlink to the file
New-Item -ItemType SymbolicLink -Path .\sfile1 -Value .\file1 | Out-Null
# Create a symlink to the folder
New-Item -ItemType SymbolicLink -Path .\sdir1 -Value .\dir1 | Out-Null
# Create a hard link to the file
New-Item -ItemType HardLink -Path .\hfile1 -Value .\file1 | Out-Null
# Create a junction to the folder
New-Item -ItemType Junction -Path .\jdir1 -Value .\dir1 | Out-Null
# View the item properties
Get-ChildItem -Path . | Sort-Object Name | Format-Table -Property Name, PSIsContainer, LinkType, Target, Attributes -AutoSize
您的输出将是:
Name PSIsContainer LinkType Target Attributes
---- ------------- -------- ------ ----------
dir1 True {} Directory
file1 False HardLink {C:\linktest\hfile1} Archive
file2 False {} Archive
hfile1 False HardLink {C:\linktest\file1} Archive
jdir1 True Junction {C:\linktest\dir1} Directory, ReparsePoint
sdir1 True SymbolicLink {C:\linktest\dir1} Directory, ReparsePoint
sfile1 False SymbolicLink {C:\linktest\file1} Archive, ReparsePoint
请注意,file1
和 hfile1
都是硬链接(hard link),即使 file1
不是这样创建的。
要清理上述垃圾,请执行以下操作:
Get-ChildItem -Path C:\linktest\ | ForEach-Object { $_.Delete() }
有a bug in Remove-Item
删除一些容器链接,这会阻止命令删除项目。
一般的解决方案是获取该项目并测试它:
# Get the item. Don't use Get-ChildItem because that will get a directory's contents
$Item = Get-Item -Path $Path
# Is it a container
$Item.PSIsContainer
# Is it a link of some kind?
[System.String]::IsNullOrWhiteSpace($Item.LinkType)
$Item.LinkType -eq 'Junction'
# Is it a Reparse Point?
($Item.Attributes -band [System.IO.FileAttributes]::ReparsePoint) -eq [System.IO.FileAttributes]::ReparsePoint
还有其他几个潜在的属性:
PS> [System.Enum]::GetNames([System.IO.FileAttributes])
ReadOnly
Hidden
System
Directory
Archive
Device
Normal
Temporary
SparseFile
ReparsePoint
Compressed
Offline
NotContentIndexed
Encrypted
IntegrityStream
NoScrubData
请注意Device
is documented as reserved for future use 。 Windows 中没有设备文件类型。
对于卷安装点,我不能 100% 确定它们的外观。我知道您可以在 Windows 8.1 及更高版本上使用 Get-Partition
创建它们,然后使用适当的 Add-PartitionAccessPath
,但我目前使用的是 Windows 7。恐怕我目前没有办法对此进行测试。
最后,我不知道 Linux 上的 PowerShell Core 6.0 到底如何处理文件类型。
关于shell - 在powershell中检查文件是否可读且正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48995968/