VB のたまご

作成日: 2015/12/03, 更新日: 2015/12/03


DirectoryNotFoundException について

概要

  •  DirectoryNotFoundException は、フォルダ読み込みの他、ファイル読み込みでも発生する例外エラーです。 実在するかどうか事前チェックすることが、解決の糸口につながります。


スポンサーリンク


事例と対処方法

  •  以下のサンプルは、意図的に例外エラーを発生させるコードです。 実際の業務プログラムでは、このような簡単なコードではないと思いますが、例外発生させている、直接的な原因となる部分として参考になるはずです。 また、本例外エラーが発生してしまう原因となった、根本的な原因となる別の例外エラーが、さらに奥深くにいる場合があります。 (本例外エラーは間接的に影響を受けて発生してしまったもので、本当の原因となる例外エラーを食い止めることで、本例外エラーも直る場合があります。)

  •  このような組み合わせのパターンは、本例外エラーに限らず、他の例外エラー全般にも言えることですが、そんなに頻繁に出くわすものではないと思いますので、 そういう場合もあるということだけ、覚えておいていただけると解決しやすくなるのではと思います。

  •  また、記載の対処方法は、あくまでも一例です。 他の対処方法の方が、その業務プログラムにとってベストプラクティスとなる場合もありますので、検討材料の1つという程度に確認していただければと思います。

  • スポンサーリンク



  • File.ReadAllText
  • Dim logFile As String = "C:\Temp\"
    Dim logData As String = File.ReadAllText(logFile)
    
    ' 例外エラー
    System.IO.DirectoryNotFoundException: パス 'C:\Temp\' の一部が見つかりませんでした。
       場所 System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
       場所 System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
       場所 System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
       場所 System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize, Boolean checkHost)
       場所 System.IO.File.InternalReadAllText(String path, Encoding encoding, Boolean checkHost)
       場所 System.IO.File.ReadAllText(String path)
    
    ' 対処方法
    Dim logFile As String = "C:\Temp\"
    If File.Exists(logFile) Then
        Dim logData As String = File.ReadAllText(logFile)
    End If
    
  •  ファイルの指定ではなくフォルダを指定していることが、そもそもの誤りです。 存在チェックを事前に行って、存在している場合のみ処理を行う対処方法です。


  • Directory.GetDirectories、その1
  • Dim targetFolder As String = "C:\Temp\sample"
    Dim subFolders() As String = Directory.GetDirectories(targetFolder)
    
    ' 例外エラー
    System.IO.DirectoryNotFoundException: パス 'C:\Temp\sample' の一部が見つかりませんでした。
       場所 System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
       場所 System.IO.FileSystemEnumerableIterator`1.CommonInit()
       場所 System.IO.FileSystemEnumerableIterator`1..ctor(String path, String originalUserPath, String searchPattern, SearchOption searchOption, SearchResultHandler`1 resultHandler, Boolean checkHost)
       場所 System.IO.Directory.GetDirectories(String path)
    
    ' 対処方法
    前の対処方法と同様
    
  •  こちらも前の事例と同様です。フォルダの存在チェックを実施します。


  • Directory.GetDirectories、その2
  • Dim targetFolder As String = "..\sample"
    Dim subFolders() As String = Directory.GetDirectories(targetFolder)
    
    ' 例外エラー
    System.IO.DirectoryNotFoundException: パス 'C:\Temp\sample' の一部が見つかりませんでした。
       場所 System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
       場所 System.IO.FileSystemEnumerableIterator`1.CommonInit()
       場所 System.IO.FileSystemEnumerableIterator`1..ctor(String path, String originalUserPath, String searchPattern, SearchOption searchOption, SearchResultHandler`1 resultHandler, Boolean checkHost)
       場所 System.IO.Directory.GetDirectories(String path)
    
    ' 対処方法
    前の対処方法と同様
    
  •  こちらも前の事例と同様ですが、パスの指定に相対パスを指定しています。 相対パスは実行ファイルの場所によってフルパスが変わってくるので、絶対パスに比べて相対パスの方が扱いが難しくなります。 可能であれば絶対パスとして扱うと把握しやすくなるのではと思います。


  • File.WriteAllText
  • Imports System.IO
    
    Dim saveFile As String = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "app\app.dat")
    File.WriteAllText(saveFile, "a")
    
    ' 例外エラー
    System.IO.DirectoryNotFoundException: パス 'xxx\app\app.dat' の一部が見つかりませんでした。
       場所 System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
       場所 System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
       場所 System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
       場所 System.IO.StreamWriter.CreateFile(String path, Boolean append, Boolean checkHost)
       場所 System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize, Boolean checkHost)
       場所 System.IO.File.InternalWriteAllText(String path, String contents, Encoding encoding, Boolean checkHost)
       場所 System.IO.File.WriteAllText(String path, String contents)
    
    ' 対処方法
    前の対処方法と同様
    
  •  今度はファイル保存時の処理です。 ファイルを保存する場合、専用フォルダを設けるのであれば、事前にそのフォルダの存在チェックと、必要であればフォルダ作成を別途実施する必要があります。 WriteAllText メソッドは、「フォルダが存在しない場合は、同時に作成する」という機能は無いからです。

  •  最後までこの記事を読んでいただき、ありがとうございました。

  • スポンサーリンク