Действительная проверка имени файла. Каков наилучший способ?
См. тему для постановки вопроса.
1) Я вспоминаю, что в VB.NET используется действительно классная опция, использующая LINQ для сопоставления с использованием "LIKE%"
2) Я знаю, что регулярные выражения будут работать, и я подозреваю, что это приведет к кратчайшему коду и, вероятно, не будет слишком трудно читать для такого простого теста.
Вот что я сделал. Предупреждение: вы будете ненавидеть.
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
Ответы
Ответ 1
Старый, но я видел это и просто должен был добавить новый ответ. Текущие принятые и другие ответы просто сложнее, чем необходимо. Фактически, его можно свести к одной строке:
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
Хотя я бы не рекомендовал писать так. Разбейте его немного, чтобы улучшить читаемость:
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
Еще один момент заключается в том, что часто лучший способ справиться с проблемами файловой системы - позволить файловой системе сказать вам: просто попробуйте открыть или создать файл, о котором идет речь, и обработать исключение. Это работает особенно хорошо, потому что вам все равно придется это делать. Все, что вы здесь делаете, - это дублирующее усилие для работы, которое вам все равно придется помещать в обработчик исключений.
Ответ 2
Как насчет Path.GetInvalidFileNameChars и Path.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
Ответ 3
Это регулярное выражение и С#, но:
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 );
}
Ответ 4
Несмотря на то, что он довольно старый, он по-прежнему действителен, и я решил найти решение о том, как проверить имя файла для недопустимых символов. Я посмотрел на принятый ответ и нашел несколько отверстий.
Надеемся, что эти модификации будут полезны кому-то другому.
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
Ответ 5
попробуйте это
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
Ответ 6
Основываясь на хорошо написанном решении 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
Ответ 7
Честно говоря, я бы просто использовал объект FileInfo, встроенный в .NET, и проверил исключение для недействительности. Подробнее см. эту ссылку.
Ответ 8
Ok. Хорошие идеи.
Но ручная итерация "недействительных" символов не является лучшим способом, когда вы работаете с тысячами файлов.
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
Ответ 9
Попробуйте это
Функция IsValidFileNameOrPath (ByVal name As String) В качестве логического
Dim я 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
Ответ 10
Я не могу взять кредит за этот (ну два) лайнер. Я нашел его в то время как поисковик не мог вспомнить, где я его нашел.
Dim newFileName As String = "*Not<A>Good:Name|For/\File?"
newFileName = String.Join("-", fileName.Split(IO.Path.GetInvalidFileNameChars))
Ответ 11
Public Function IsValidFileName(nFile As String) As Boolean
Try
Dim S As String = Path.GetFileName(nFile)
Catch
Return False
End Try
Return True
End Function