skip to Main Content

Visual Studio 2012
VB.NET Windows forms application
.NET Framework 4.5.2

VB has finally won. I am out of ideas.

The File.WriteAllText function throws the exception "Could not find file" even though MS says that it can only throw the following exceptions (MS documentation):

‘ Exceptions:
‘ T:System.ArgumentException:
‘ path is a zero-length string, contains only white space, or >contains one or more
‘ invalid characters as defined by >System.IO.Path.InvalidPathChars.

‘ T:System.ArgumentNullException:
‘ path is null or contents is empty.

‘ T:System.IO.PathTooLongException:
‘ The specified path, file name, or both exceed the system->
defined maximum length.
‘ For example, on Windows-based platforms, paths must be less >
than 248 characters,
‘ and file names must be less than 260 characters.

‘ T:System.IO.DirectoryNotFoundException:
‘ The specified path is invalid (for example, it is on an unmapped drive).

‘ T:System.IO.IOException:
‘ An I/O error occurred while opening the file.

‘ T:System.UnauthorizedAccessException:
‘ path specified a file that is read-only.-or- This operation is not supported
‘ on the current platform.-or- path specified a directory.-or- The caller does
‘ not have the required permission.

‘ T:System.NotSupportedException:
‘ path is in an invalid format.

‘ T:System.Security.SecurityException:
‘ The caller does not have the required permission.

The code (it worked last week):

Dim filepath As String = StringFilePath + "" + DateTime.Now.ToString("yyyy/MM")
Dim stringFile As String = ""
If My.Computer.FileSystem.DirectoryExists(filepath) = False Then
    My.Computer.FileSystem.CreateDirectory(filepath)
End If

stringFile = StringHTMLHeader + StringTestDoc + StringHTMLFooter

StringLastSavedFile = Path.Combine(filepath, "Test Result " + DateTime.Now.ToString("dd-HH-mm-ss") + ".htm")

Try
    File.WriteAllText(StringLastSavedFile, stringFile)
Catch ex As Exception
End Try
  • Checking the filepath etc. etc.
  • Running as admin
  • And, of course, restarting.

2

Answers


  1. I tried the following code and it worked. I had to guess at some of the variables based on the various comments.

        Dim StringLastSavedFile As String = ""
        Dim StringFilePath As String = IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Tester")
    
        Dim filepath As String = IO.Path.Combine(StringFilePath, DateTime.Now.ToString("yyyy-MM"))
        Dim stringFile As String = ""
        If Not IO.Directory.Exists(filepath) Then
            IO.Directory.CreateDirectory(filepath)
        End If
    
        stringFile = "TEST DATA" '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    
        StringLastSavedFile = IO.Path.Combine(filepath, "Test Result " & DateTime.Now.ToString("dd-HH-mm-ss") & ".htm")
    
        Try
            IO.File.WriteAllText(StringLastSavedFile, stringFile)
        Catch ex As Exception
            Stop
        End Try
    
    Login or Signup to reply.
  2. This code is unnecessary:

    If My.Computer.FileSystem.DirectoryExists(filepath) = False Then
    

    Note this in the documentation for the CreateDirectory() method:

    If the directory already exists, no exception is thrown.

    Since disk I/O is possibly the slowest thing you can do in a single computer, it’s worth removing this wasteful check to call CreateDirectory() all the time, with no If conditional check first.

    It’s also a bad idea to wrap the file I/O in a Try/Catch that just swallows the exception. You may indeed want a try/catch, but if so put it up at a higher level, or least respond to the exception.

    Additionally, the / character from the folder path is not valid on windows, and will create another directory level on unix systems. We also can’t see the StringFilePath variable to know if there are other invalid characters.

    Lastly, adding type info to variable names hasn’t been considered good practice since at least 2004. Stop putting "String" or similar as part of the variable names (but do still provide a type when declaring variables), and try to declare variables to have short scopes (ie: declare them near where they’re used), so they can be collected efficiently.

    Put it all together like this:

    Dim filepath As String = IO.Path.Combine(StringFilePath, DateTime.Now.ToString("yyyy-MM"))
    My.Computer.FileSystem.CreateDirectory(filepath)
    
    Dim fileData As String = HTMLHeader & TestDoc & HTMLFooter
    Dim fullFileName = Path.Combine(filepath, "Test Result " + DateTime.Now.ToString("dd-HH-mm-ss") & ".htm")
    
    File.WriteAllText(fullFileName, fileData)
    

    Oh, and one more thing. Take special note of this item from the exceptions:

    System.Security.SecurityException: The caller does not have the required permission.

    You’ll need to investigate that more completely.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search