Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Selain pengecualian yang dapat dilemparkan dalam panggilan metode apa pun (seperti OutOfMemoryException ketika sistem stres atau NullReferenceException karena kesalahan pemrogram), metode sistem file .NET dapat melemparkan pengecualian berikut:
- System.IO.IOException, kelas dasar dari semua System.IO jenis pengecualian. Ini dilemparkan untuk kesalahan yang kode pengembaliannya dari sistem operasi tidak sesuai langsung dengan jenis pengecualian lainnya.
- System.IO.FileNotFoundException.
- System.IO.DirectoryNotFoundException.
- DriveNotFoundException.
- System.IO.PathTooLongException.
- System.OperationCanceledException.
- System.UnauthorizedAccessException.
- System.ArgumentException, yang dilemparkan karena terdapat karakter jalur yang tidak valid pada .NET Framework serta .NET Core 2.0 dan versi sebelumnya.
- System.NotSupportedException, yang digunakan untuk menangani kesalahan titik dua yang tidak valid dalam .NET Framework.
- System.Security.SecurityException, yang dilemparkan untuk aplikasi yang berjalan dalam kepercayaan terbatas yang tidak memiliki izin yang diperlukan pada .NET Framework saja. (Kepercayaan penuh adalah default pada .NET Framework.)
Memetakan kode kesalahan ke pengecualian
Karena sistem file adalah sumber daya sistem operasi, metode I/O dalam .NET Core dan .NET Framework melakukan pemanggilan ke sistem operasi yang mendasari. Ketika kesalahan I/O terjadi dalam kode yang dijalankan oleh sistem operasi, sistem operasi mengembalikan informasi kesalahan ke metode .NET I/O. Metode ini kemudian menerjemahkan informasi kesalahan, biasanya dalam bentuk kode kesalahan, ke dalam jenis pengecualian .NET. Dalam kebanyakan kasus, ia melakukan ini dengan langsung menerjemahkan kode kesalahan ke dalam jenis pengecualian yang sesuai; ini tidak melakukan pemetaan khusus kesalahan berdasarkan konteks panggilan metode.
Misalnya, pada sistem operasi Windows, panggilan metode yang mengembalikan kode kesalahan ERROR_FILE_NOT_FOUND (atau 0x02) dipetakan ke FileNotFoundException, dan kode kesalahan ERROR_PATH_NOT_FOUND (atau 0x03) dipetakan ke DirectoryNotFoundException.
Namun, kondisi yang tepat di mana sistem operasi mengembalikan kode kesalahan tertentu sering tidak terdokumentasi atau didokumentasikan dengan buruk. Akibatnya, pengecualian tak terduga dapat terjadi. Misalnya, karena Anda bekerja dengan direktori, bukan file, Anda akan mengharapkan bahwa jika menyediakan jalur direktori yang tidak valid ke konstruktor DirectoryInfo, akan menghasilkan lemparan DirectoryNotFoundException. Namun, mungkin juga melempar FileNotFoundException.
Penanganan pengecualian dalam operasi I/O
Karena ketergahan ini pada sistem operasi, kondisi pengecualian yang identik (seperti direktori tidak menemukan kesalahan dalam contoh kami) dapat mengakibatkan metode I/O melempar salah satu dari seluruh kelas pengecualian I/O. Ini berarti bahwa, saat memanggil API I/O, kode Anda harus disiapkan untuk menangani sebagian besar atau semua pengecualian ini, seperti yang ditunjukkan dalam tabel berikut:
| Jenis pengecualian | .NET Core/.NET 5+ | .NET Framework |
|---|---|---|
| IOException | Ya | Ya |
| FileNotFoundException | Ya | Ya |
| DirectoryNotFoundException | Ya | Ya |
| DriveNotFoundException | Ya | Ya |
| PathTooLongException | Ya | Ya |
| OperationCanceledException | Ya | Ya |
| UnauthorizedAccessException | Ya | Ya |
| ArgumentException | .NET Core 2.0 dan yang lebih lama | Ya |
| NotSupportedException | Tidak. | Ya |
| SecurityException | Tidak. | Kepercayaan terbatas saja |
Menangani IOException
Sebagai kelas dasar untuk pengecualian di System.IO namespace, IOException juga dilemparkan untuk setiap kode kesalahan yang tidak sesuai dengan jenis pengecualian yang telah ditentukan sebelumnya. Ini berarti bahwa itu dapat dilemparkan oleh operasi I/O apa pun.
Penting
Karena IOException adalah kelas dasar dari jenis pengecualian lain di System.IO namespace, Anda harus menangani di catch blok setelah Anda menangani pengecualian terkait I/O lainnya.
Selain itu, dimulai dengan .NET Core 2.1, pemeriksaan validasi jalur (misalnya, untuk memastikan bahwa karakter yang tidak valid tidak ada di jalur) telah dihapus, dan runtime melemparkan pengecualian yang dipetakan dari kode kesalahan sistem operasi, bukan menggunakan kode validasinya sendiri. Pengecualian yang paling mungkin untuk dilemparkan dalam kasus ini adalah IOException, meskipun jenis pengecualian lainnya juga dapat dilemparkan.
Perhatikan bahwa, dalam kode penanganan pengecualian Anda, Anda harus selalu menangani yang IOException terakhir. Jika tidak, karena ini adalah kelas dasar dari semua pengecualian IO lainnya, blok tangkapan kelas turunan tidak akan dievaluasi.
Dalam kasus IOException, Anda bisa mendapatkan informasi kesalahan tambahan dari properti IOException.HResult . Untuk mengonversi nilai HResult ke kode kesalahan Win32, Anda menghapus 16 bit atas dari nilai 32-bit. Tabel berikut mencantumkan kode kesalahan yang mungkin dibungkus dalam IOException.
| Hresult | Konstanta | Deskripsi |
|---|---|---|
| KESALAHAN_PELANGGARAN_BAGI_PAKAI | 32 | Nama file hilang, atau file atau direktori sedang digunakan. |
| KESALAHAN_FILE_ADA | 80 | File sudah ada. |
| KESALAHAN_PARAMETER_TIDAK_VALID | 87 | Argumen yang diberikan ke metode tidak valid. |
| Error_Sudah_Ada | 183 | File atau direktori sudah ada. |
Anda dapat menanganinya menggunakan When klausul dalam pernyataan catch, seperti yang ditunjukkan contoh berikut.
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