Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Outre les exceptions pouvant être levées dans n’importe quel appel de méthode (par OutOfMemoryException exemple, lorsqu’un système est stressé ou en raison d’une NullReferenceException erreur de programmeur), les méthodes de système de fichiers .NET peuvent lever les exceptions suivantes :
- System.IO.IOException, classe de base de tous les System.IO types d’exceptions. Elle est levée pour les erreurs dont les codes de retour du système d’exploitation ne correspondent de façon directe à aucun autre type d'exception.
- System.IO.FileNotFoundException.
- System.IO.DirectoryNotFoundException.
- DriveNotFoundException.
- System.IO.PathTooLongException.
- System.OperationCanceledException.
- System.UnauthorizedAccessException.
- System.ArgumentException, qui est générée pour les caractères de chemin d’accès non valides sur .NET Framework et sur .NET Core 2.0 et les versions antérieures.
- System.NotSupportedException, qui est générée pour les deux-points non valides dans .NET Framework.
- System.Security.SecurityException, qui est générée pour les applications exécutées dans un environnement de confiance limitée et ne disposant pas des permissions nécessaires sur .NET Framework uniquement. (La confiance totale est la valeur par défaut sur .NET Framework.)
Mappage des codes d’erreur aux exceptions
Étant donné que le système de fichiers est une ressource de système d’exploitation, les méthodes d’E/S dans .NET Core et .NET Framework encapsulent les appels au système d’exploitation sous-jacent. Lorsqu’une erreur d’E/S se produit dans le code exécuté par le système d’exploitation, le système d’exploitation retourne des informations d’erreur à la méthode d’E/S .NET. La méthode traduit ensuite les informations d’erreur, généralement sous la forme d’un code d’erreur, en type d’exception .NET. Dans la plupart des cas, elle effectue cette opération en convertissant directement le code d’erreur en son type d’exception correspondant ; elle n’effectue aucun mappage spécial de l’erreur en fonction du contexte de l’appel de méthode.
Par exemple, sur le système d’exploitation Windows, un appel de méthode qui retourne un code d’erreur ( ERROR_FILE_NOT_FOUND ou 0x02) est mappé à un FileNotFoundException, et un code d’erreur de ERROR_PATH_NOT_FOUND (ou 0x03) est mappé à un DirectoryNotFoundException.
Toutefois, les conditions précises dans lesquelles le système d’exploitation retourne des codes d’erreur particuliers sont souvent non documentées ou mal documentées. Par conséquent, des exceptions inattendues peuvent se produire. Par exemple, étant donné que vous travaillez avec un répertoire plutôt qu’un fichier, vous vous attendez à ce que fournir un chemin de répertoire non valide au constructeur DirectoryInfo provoque une exception DirectoryNotFoundException. Toutefois, une exception FileNotFoundException peut également être levée.
Gestion des exceptions dans les opérations d’E/S
En raison de cette dépendance sur le système d’exploitation, des conditions d’exception identiques (telles que l’erreur de répertoire introuvable dans notre exemple) peuvent entraîner une méthode d’E/S qui lève l’une des classes entières d’exceptions d’E/S. Cela signifie que, lors de l’appel d’API d’E/S, votre code doit être prêt à gérer la plupart ou l’ensemble de ces exceptions, comme indiqué dans le tableau suivant :
| Type d’exception | .NET Core/.NET 5+ | .NET Framework |
|---|---|---|
| IOException | Oui | Oui |
| FileNotFoundException | Oui | Oui |
| DirectoryNotFoundException | Oui | Oui |
| DriveNotFoundException | Oui | Oui |
| PathTooLongException | Oui | Oui |
| OperationCanceledException | Oui | Oui |
| UnauthorizedAccessException | Oui | Oui |
| ArgumentException | .NET Core 2.0 et versions antérieures | Oui |
| NotSupportedException | Non | Oui |
| SecurityException | Non | Confiance limitée uniquement |
Gestion d’IOException
Comme classe de base pour les exceptions dans l'espace de noms System.IO, IOException est également levée pour tout code d'erreur qui ne correspond pas à un type d'exception prédéfini. Cela signifie qu’elle peut être levée par n’importe quelle opération E/S.
Importante
Parce que IOException est la classe de base des autres types d'exceptions dans l'espace de noms System.IO, vous devriez le gérer dans un bloc catch une fois que vous avez traité les autres exceptions liées aux E/S.
En outre, à compter de .NET Core 2.1, les vérifications de validation de la correction du chemin d’accès (par exemple, pour s’assurer que les caractères non valides ne sont pas présents dans un chemin) ont été supprimés, et le runtime lève une exception mappée à partir d’un code d’erreur du système d’exploitation plutôt que de son propre code de validation. L’exception la plus probable à lever dans ce cas est un IOException, bien que tout autre type d’exception puisse également être levée.
Notez que, dans votre code de gestion des exceptions, vous devez toujours gérer le IOException dernier. Sinon, étant donné qu’il s’agit de la classe de base de toutes les autres exceptions d’E/S, les blocs catch des classes dérivées ne seront pas évalués.
Dans le cas d’un IOException, vous pouvez obtenir des informations d’erreur supplémentaires à partir de la propriété IOException.HResult . Pour convertir la valeur HResult en code d’erreur Win32, vous supprimez les 16 bits supérieurs de la valeur 32 bits. Le tableau suivant répertorie les codes d’erreur qui peuvent être encapsulés dans un IOException.
| HResult | Constante | Descriptif |
|---|---|---|
| ERREUR_DE_VIOLATION_DE_PARTAGE | 32 | Le nom de fichier est manquant ou le fichier ou le répertoire est en cours d’utilisation. |
| ERROR_FILE_EXISTS | 80 | Le fichier existe déjà. |
| ERREUR_PARAMÈTRE_INVALIDE | 87 | Un argument fourni à la méthode n’est pas valide. |
| ERREUR_DEJA_EXISTE | 183 | Le fichier ou le répertoire existe déjà. |
Vous pouvez les gérer à l’aide d’une When clause dans une instruction catch, comme l’illustre l’exemple suivant.
using System;
using System.IO;
using System.Text;
class Program
{
static void Main()
{
var sw = OpenStream(@".\textfile.txt");
if (sw is null)
return;
sw.WriteLine("This is the first line.");
sw.WriteLine("This is the second line.");
sw.Close();
}
static StreamWriter? OpenStream(string path)
{
if (path is null)
{
Console.WriteLine("You did not supply a file path.");
return null;
}
try
{
var fs = new FileStream(path, FileMode.CreateNew);
return new StreamWriter(fs);
}
catch (FileNotFoundException)
{
Console.WriteLine("The file or directory cannot be found.");
}
catch (DirectoryNotFoundException)
{
Console.WriteLine("The file or directory cannot be found.");
}
catch (DriveNotFoundException)
{
Console.WriteLine("The drive specified in 'path' is invalid.");
}
catch (PathTooLongException)
{
Console.WriteLine("'path' exceeds the maximum supported path length.");
}
catch (UnauthorizedAccessException)
{
Console.WriteLine("You do not have permission to create this file.");
}
catch (IOException e) when ((e.HResult & 0x0000FFFF) == 32)
{
Console.WriteLine("There is a sharing violation.");
}
catch (IOException e) when ((e.HResult & 0x0000FFFF) == 80)
{
Console.WriteLine("The file already exists.");
}
catch (IOException e)
{
Console.WriteLine($"An exception occurred:\nError code: " +
$"{e.HResult & 0x0000FFFF}\nMessage: {e.Message}");
}
return null;
}
}
Imports System.IO
Module Program
Sub Main(args As String())
Dim sw = OpenStream(".\textfile.txt")
If sw Is Nothing Then Return
sw.WriteLine("This is the first line.")
sw.WriteLine("This is the second line.")
sw.Close()
End Sub
Function OpenStream(path As String) As StreamWriter
If path Is Nothing Then
Console.WriteLine("You did not supply a file path.")
Return Nothing
End If
Try
Dim fs As New FileStream(path, FileMode.CreateNew)
Return New StreamWriter(fs)
Catch e As FileNotFoundException
Console.WriteLine("The file or directory cannot be found.")
Catch e As DirectoryNotFoundException
Console.WriteLine("The file or directory cannot be found.")
Catch e As DriveNotFoundException
Console.WriteLine("The drive specified in 'path' is invalid.")
Catch e As PathTooLongException
Console.WriteLine("'path' exceeds the maximum supported path length.")
Catch e As UnauthorizedAccessException
Console.WriteLine("You do not have permission to create this file.")
Catch e As IOException When (e.HResult And &h0000FFFF) = 32
Console.WriteLine("There is a sharing violation.")
Catch e As IOException When (e.HResult And &h0000FFFF) = 80
Console.WriteLine("The file already exists.")
Catch e As IOException
Console.WriteLine($"An exception occurred:{vbCrLf}Error code: " +
$"{e.HResult And &h0000FFFF}{vbCrLf}Message: {e.Message}")
End Try
Return Nothing
End Function
End Module