vb.net 有效的文件名检查。什么是最好的方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1014242/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 14:16:23  来源:igfitidea点击:

Valid filename check. What is the best way?

vb.net

提问by Chad

See subject of positing for question.

见问题的定位主题。

1) I recall seeing a really cool option in VB.NET using LINQ to match using "LIKE%'

1) 我记得在 VB.NET 中看到一个非常酷的选项,使用 LINQ 来匹配使用“LIKE%”

2) I know regular expressions will work and I suspect that will result in the shortest code and probably won't be too hard to read for such a simple test.

2)我知道正则表达式会起作用,我怀疑这会产生最短的代码,并且对于这样一个简单的测试来说可能不会太难阅读。

Here's what I did. Warning: You're gonna hate it.

这就是我所做的。警告:你会讨厌它。

Private Shared Function FileNameIsOk(ByVal fileName As String) As Boolean

    For Position As Integer = 0 To fileName.Length - 1

        Dim Character As String = fileName.Substring(Position, 1).ToUpper
        Dim AsciiCharacter As Integer = Asc(Character)

        Select Case True

            Case Character = "_" 'allow _
            Case Character = "." 'allow .
            Case AsciiCharacter >= Asc("A") And AsciiCharacter <= Asc("A") 'Allow alphas
            Case AsciiCharacter >= Asc("0") AndAlso AsciiCharacter <= Asc("9") 'allow digits

            Case Else 'otherwise, invalid character
                Return False

        End Select

    Next

    Return True

End Function

回答by Joel Coehoorn

Old now, but I saw this and just had to add a new answer. The current accepted and other answers are way more complicated than needed. In fact, it can be reduced to a single line:

现在旧了,但我看到了这个,只好添加一个新答案。当前接受的答案和其他答案比需要的要复杂得多。事实上,它可以简化为一行:

Public Shared Function FilenameIsOK(ByVal fileName as String) as Boolean
    Return Not (Path.GetFileName(fileName).Intersect(Path.GetInvalidFileNameChars()).Any() OrElse Path.GetDirectoryName(fileName).Intersect(Path.GetInvalidPathChars()).Any()) 
End Function

Though I wouldn't recommend writing it that way. Break it up just a little bit to improve readability:

虽然我不建议那样写。稍微分解一下以提高可读性:

Public Shared Function FilenameIsOK(ByVal fileName as String) as Boolean
    Dim file As String = Path.GetFileName(fileName)
    Dim directory As String = Path.GetDirectoryName(fileName)

    Return Not (file.Intersect(Path.GetInvalidFileNameChars()).Any() _
                OrElse _ 
                directory.Intersect(Path.GetInvalidPathChars()).Any()) 
End Function

One other point here, is often the best way to deal with file system issues is to let the file system tell you: try to open or create the file in question, and deal with the exception. This works especially well, because you'll likely have to do this anyway. Any other validation you do here is duplicated effort for work you'll still have to put into an exception handler.

这里的另一点,通常是处理文件系统问题的最佳方法是让文件系统告诉您:尝试打开或创建有问题的文件,并处理异常。这特别有效,因为无论如何您都可能不得不这样做。您在此处执行的任何其他验证都是重复的工作,您仍然必须将其放入异常处理程序中。

回答by Bob King

How about Path.GetInvalidFileNameCharsand Path.GetInvalidPathChars?

如何Path.GetInvalidFileNameCharsPath.GetInvalidPathChars

Public Shared Function FilenameIsOK(ByVal fileNameAndPath as String) as Boolean
    Dim fileName = Path.GetFileName(fileNameAndPath)
    Dim directory = Path.GetDirectoryName(fileNameAndPath)
    For each c in Path.GetInvalidFileNameChars()
        If fileName.Contains(c) Then
            Return False
        End If
    Next
    For each c in Path.GetInvalidPathChars()
        If directory.Contains(c) Then
            Return False
        End If
    Next
    Return True
End Function

回答by Dana Holt

It is a regex and C# but:

它是一个正则表达式和 C#,但是:

using System;
using System.Text.RegularExpressions;

/// <summary>
/// Gets whether the specified path is a valid absolute file path.
/// </summary>
/// <param name="path">Any path. OK if null or empty.</param>
static public bool IsValidPath( string path )
{
    Regex r = new Regex( @"^(([a-zA-Z]\:)|(\))(\{1}|((\{1})[^\]([^/:*?<>""|]*))+)$" );
    return r.IsMatch( path );
}

回答by DrMarbuse

Based on Joel Coehoorns well written solution, I added some additional functionality for validation.

基于 Joel Coehoorns 写得很好的解决方案,我添加了一些额外的验证功能。

    ''' <summary>
    ''' Check if fileName is OK
    ''' </summary>
    ''' <param name="fileName">FileName</param>
    ''' <param name="allowPathDefinition">(optional) set true to allow path definitions. If set to false only filenames are allowed</param>
    ''' <param name="firstCharIndex">(optional) return the index of first invalid character</param>
    ''' <returns>true if filename is valid</returns>
    ''' <remarks>
    ''' based on Joel Coehoorn answer in 
    ''' http://stackoverflow.com/questions/1014242/valid-filename-check-what-is-the-best-way
    ''' </remarks>
    Public Shared Function FilenameIsOK(ByVal fileName As String, _
                                        Optional ByVal allowPathDefinition As Boolean = False, _
                                        Optional ByRef firstCharIndex As Integer = Nothing) As Boolean

        Dim file As String = String.Empty
        Dim directory As String = String.Empty

        If allowPathDefinition Then
            file = Path.GetFileName(fileName)
            directory = Path.GetDirectoryName(fileName)
        Else
            file = fileName
        End If

        If Not IsNothing(firstCharIndex) Then
            Dim f As IEnumerable(Of Char)
            f = file.Intersect(Path.GetInvalidFileNameChars())
            If f.Any Then
                firstCharIndex = Len(directory) + file.IndexOf(f.First)
                Return False
            End If

            f = directory.Intersect(Path.GetInvalidPathChars())
            If f.Any Then
                firstCharIndex = directory.IndexOf(f.First)
                Return False
            Else
                Return True
            End If
        Else
            Return Not (file.Intersect(Path.GetInvalidFileNameChars()).Any() _
                        OrElse _
                        directory.Intersect(Path.GetInvalidPathChars()).Any())
        End If

    End Function

回答by Kon

I cannot take credit for this one (well two) liner. I found it whilst googling-cant remember where I found it.

我不能相信这一个(以及两个)班轮。我在谷歌搜索时找到了它 - 不记得我在哪里找到它。

    Dim newFileName As String = "*Not<A>Good:Name|For/\File?"
    newFileName = String.Join("-", fileName.Split(IO.Path.GetInvalidFileNameChars))

回答by Paul Farry

Even though this is quite old, it's still valid, and I ended up here looking for the solution to how to check the filename for invalid characters. I looked at the accepted answer and found a few holes.

尽管这已经很老了,但它仍然有效,我最终在这里寻找如何检查文件名中的无效字符的解决方案。我查看了接受的答案,发现了一些漏洞。

Hopefully these modifications are of some use to someone else.

希望这些修改对其他人有用。

Public Function FilenameIsOK(ByVal fileNameAndPath As String) As Boolean
    Dim fileName As String = String.Empty
    Dim theDirectory As String = fileNameAndPath

    Dim p As Char = Path.DirectorySeparatorChar

    Dim splitPath() As String
    splitPath = fileNameAndPath.Split(p)
    If splitPath.Length > 1 Then
        fileName = splitPath(splitPath.Length - 1)
        theDirectory = String.Join(p, splitPath, 0, splitPath.Length - 1)
    End If

    For Each c As Char In Path.GetInvalidFileNameChars()
        If fileName.Contains(c) Then
            Return False
        End If
    Next

    For Each c As Char In Path.GetInvalidPathChars()
        If theDirectory.Contains(c) Then
            Return False
        End If
    Next
    Return True
End Function

回答by Hedi Guizani

try this

尝试这个

Public Function IsValidFileName(ByVal fn As String) As Boolean
    Try
        Dim fi As New IO.FileInfo(fn)
    Catch ex As Exception
        Return False
    End Try
    Return True
End Function

回答by Paul Sonier

Frankly, I'd just use the FileInfo object built in to .NET, and check for an exception for invalidity. See thisreference for details.

坦率地说,我只是使用内置于 .NET 的 FileInfo 对象,并检查无效异常。有关详细信息,请参阅参考资料。

回答by user3190427

Try this

尝试这个

Function IsValidFileNameOrPath(ByVal name As String) As Boolean

函数 IsValidFileNameOrPath(ByVal name As String) As Boolean

Dim i As Integer Dim dn, fn As String

Dim i As Integer Dim dn, fn As String

    i = InStrRev(name, "\") : dn = Mid(name, 1, i) : fn = Mid(name, i + 1)
    MsgBox("directory = " & dn & " : file = " & fn)

    If name Is Nothing Or Trim(fn) = "" Then
        MsgBox("null filename" & fn)
        Return False
    Else
        For Each badchar As Char In Path.GetInvalidFileNameChars
            If InStr(fn, badchar) > 0 Then
                MsgBox("invalid filename" & fn)
                Return False
            End If
        Next
    End If

    If dn <> "" Then
        If InStr(dn, "\") > 0 Then
            MsgBox("duplicate \ =  " & dn)
            Return False
        End If
        For Each badChar As Char In Path.GetInvalidPathChars
            If InStr(dn, badChar) > 0 Then
                MsgBox("invalid directory=  " & dn)
                Return False
            End If
        Next
        If Not System.IO.Directory.Exists(dn) Then
            Try
                Directory.CreateDirectory(dn)
                'Directory.Delete(dn)
            Catch
                MsgBox("invalid path =  " & dn)
                Return False
            End Try
        End If
    End If
    Return True
End Function

回答by Public Escobar

Ok. Good ideas. But manual iteration of 'invalid' chars is not the best way, when you work with thousands of files.

好的。好主意。但是,当您处理数千个文件时,手动迭代“无效”字符并不是最好的方法。

Public BadChars() As Char = IO.Path.GetInvalidFileNameChars

For m = 0 To thousands_of_files - 1
    '..
    if currFile.Name.ToCharArray.Intersect(BadChars).Count > 1 Then
         ' the Name is invalid - what u gonna do? =)
    end if
    '..
    '..
Next