Reputation: 24689
See subject of positing for question.
1) I recall seeing a really cool option in VB.NET using LINQ to match using "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.
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
Upvotes: 13
Views: 38863
Reputation: 1
Try this
Function IsValidFileNameOrPath(ByVal name As String) As Boolean
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
Upvotes: 0
Reputation: 31
This is a easy way works, even on folders:
Try
My.Computer.FileSystem.WriteAllText("aux", "Hello World!", False)
Catch ex As Exception
'do nothing or inform the user
End Try
Upvotes: -1
Reputation: 415765
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.
Upvotes: 16
Reputation: 1
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
Upvotes: 0
Reputation: 21
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))
Upvotes: 2
Reputation: 870
Based on Joel Coehoorns well written solution, I added some additional functionality for validation.
''' <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
Upvotes: 1
Reputation: 31
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
Upvotes: 0
Reputation: 21
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
Upvotes: 1
Reputation: 4768
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
Upvotes: 2
Reputation: 25856
How about Path.GetInvalidFileNameChars and 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
Upvotes: 10
Reputation: 12816
It is a regex and C# but:
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 );
}
Upvotes: 2
Reputation: 39480
Frankly, I'd just use the FileInfo object built in to .NET, and check for an exception for invalidity. See this reference for details.
Upvotes: 1