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.
Penyimpanan pencadangan adalah media penyimpanan, seperti disk atau memori. Setiap jenis penyimpanan pendukung mengimplementasikan alirannya sendiri sebagai turunan dari kelas Stream.
Setiap jenis aliran membaca dan menulis byte dari dan ke penyimpanan dasar yang diberikan. Aliran yang terhubung ke penyimpanan pendukung disebut aliran dasar. Aliran dasar memiliki konstruktor dengan parameter yang diperlukan untuk menghubungkan aliran ke penyimpanan pendukung. Misalnya, FileStream memiliki konstruktor yang menentukan parameter mode akses, yang menentukan apakah file dibaca dari, ditulis ke, atau keduanya.
Desain kelas System.IO menyediakan komposisi aliran yang disederhanakan. Anda dapat melampirkan aliran dasar ke satu atau beberapa aliran pass-through yang menyediakan fungsionalitas yang Anda inginkan. Anda dapat melampirkan pembaca atau penulis ke ujung rantai, sehingga jenis yang disukai dapat dibaca atau ditulis dengan mudah.
Prasyarat
Contoh-contoh ini menggunakan file teks biasa bernama data.txt. File ini harus berisi beberapa teks.
Contoh: Mengenkripsi dan mendekripsi data aliran
Contoh berikut membaca data dari file, mengenkripsinya, lalu menulis data terenkripsi ke file lain. Komposisi aliran digunakan untuk mengubah data menggunakan cipher pergeseran dasar. Setiap byte yang melewati aliran memiliki nilainya berubah sebesar 80.
Peringatan
Enkripsi yang digunakan dalam contoh ini dasar dan tidak aman. Ini tidak dimaksudkan untuk benar-benar mengenkripsi data untuk digunakan, tetapi disediakan untuk menunjukkan perubahan data melalui komposisi aliran.
Membaca data sumber untuk enkripsi
Kode berikut membaca teks dari satu file, mengubahnya, lalu menulisnya ke file lain.
Petunjuk / Saran
Sebelum meninjau kode ini, ketahuilah bahwa CipherStream adalah jenis yang ditentukan pengguna. Kode untuk kelas ini disediakan di bagian kelas CipherStream.
void WriteShiftedFile()
{
// Create the base streams for the input and output files
using FileStream inputBaseStream = File.OpenRead("data.txt");
using CipherStream encryptStream = CipherStream.CreateForRead(inputBaseStream);
using FileStream outputBaseStream = File.Open("shifted.txt", FileMode.Create, FileAccess.Write);
int intValue;
// Read byte from inputBaseStream through the encryptStream (normal bytes into shifted bytes)
while ((intValue = encryptStream.ReadByte()) != -1)
{
outputBaseStream.WriteByte((byte)intValue);
}
// Process is:
// (inputBaseStream -> encryptStream) -> outputBaseStream
}
Sub WriteShiftedFile()
'Create the base streams for the input and output files
Using inputBaseStream As FileStream = File.OpenRead("data.txt")
Using encryptStream As CipherStream = CipherStream.CreateForRead(inputBaseStream)
Using outputBaseStream As FileStream = File.Open("shifted.txt", FileMode.Create, FileAccess.Write)
'Read byte from inputBaseStream through the encryptStream (normal bytes into shifted bytes)
Dim intValue As Integer = encryptStream.ReadByte()
While intValue <> -1
outputBaseStream.WriteByte(Convert.ToByte(intValue))
intValue = encryptStream.ReadByte()
End While
End Using
End Using
End Using
'Process is:
' (inputBaseStream -> encryptStream) -> outputBaseStream
End Sub
Pertimbangkan aspek-aspek berikut tentang kode sebelumnya:
- Ada dua FileStream objek:
- Objek (
FileStreamvariabel) pertamainputBaseStreammembaca konten file data.txt. Ini adalah stream data masukan. - Objek kedua
FileStream(outputBaseStreamvariabel) menulis data masuk ke file shifted.txt . Ini adalah aliran data output .
- Objek (
- Objek
CipherStream(encryptStreamvariabel) membungkusinputBaseStream, membuatinputBaseStreamaliran dasar untukencryptStream.
Aliran input dapat dibaca dari secara langsung, menulis data ke aliran output, tetapi itu tidak akan mengubah data. Sebagai gantinya, pembungkus encryptStream aliran input digunakan untuk membaca data. Saat data dibaca dari encryptStream, data itu diambil dari inputBaseStream aliran dasar, mengubahnya, dan mengembalikannya. Data yang dikembalikan ditulis ke outputBaseStream, yang memindahkan data ke shifted.txt.
Membaca data yang diubah untuk dekripsi
Kode ini membalikkan enkripsi yang dilakukan oleh kode sebelumnya:
void ReadShiftedFile()
{
int intValue;
// Create the base streams for the input and output files
using FileStream inputBaseStream = File.OpenRead("shifted.txt");
using FileStream outputBaseStream = File.Open("unshifted.txt", FileMode.Create, FileAccess.Write);
using CipherStream unencryptStream = CipherStream.CreateForWrite(outputBaseStream);
// Read byte from inputBaseStream through the encryptStream (shifted bytes into normal bytes)
while ((intValue = inputBaseStream.ReadByte()) != -1)
{
unencryptStream.WriteByte((byte)intValue);
}
// Process is:
// inputBaseStream -> (encryptStream -> outputBaseStream)
}
Sub ReadShiftedFile()
'Create the base streams for the input and output files
Using inputBaseStream As FileStream = File.OpenRead("shifted.txt")
Using outputBaseStream As FileStream = File.Open("unshifted.txt", FileMode.Create, FileAccess.Write)
Using unencryptStream As CipherStream = CipherStream.CreateForWrite(outputBaseStream)
'Read byte from inputBaseStream through the encryptStream (shifted bytes into normal bytes)
Dim intValue As Integer = inputBaseStream.ReadByte()
While intValue <> -1
unencryptStream.WriteByte(Convert.ToByte(intValue))
intValue = inputBaseStream.ReadByte()
End While
End Using
End Using
End Using
End Sub
Pertimbangkan aspek-aspek berikut tentang kode sebelumnya:
- Ada dua FileStream objek:
- Objek
FileStream(inputBaseStreamvariabel) pertama membaca isi dari shifted.txt. Ini adalah aliran data input . - Objek kedua
FileStream(outputBaseStreamvariabel) akan menulis data masuk ke berkas unshifted.txt. Ini adalah aliran data output .
- Objek
- Objek
CipherStream(unencryptStreamvariabel) membungkusoutputBaseStream, membuatoutputBaseStreamaliran dasar untukunencryptStream.
Di sini, kode sedikit berbeda dari contoh sebelumnya. Alih-alih membungkus aliran input, unencryptStream membungkus aliran output. Saat data dibaca dari inputBaseStream aliran input, data dikirim ke unencryptStream pembalut aliran output. Saat unencryptStream menerima data, ia mengubah data tersebut lalu menulisnya ke aliran dasar outputBaseStream. Aliran keluaran outputBaseStream menulis data ke dalam file unshifted.txt.
Memvalidasi data yang diubah
Dua contoh sebelumnya melakukan dua operasi pada data. Pertama, konten file data.txt dienkripsi dan disimpan ke file shifted.txt . Dan kedua, konten terenkripsi dari file shifted.txt didekripsi dan disimpan ke file unshifted.txt . Oleh karena itu, file data.txt dan file unshifted.txt harus sama persis. Kode berikut membandingkan file-file tersebut untuk kesetaraan:
bool IsShiftedFileValid()
{
// Read the shifted file
string originalText = File.ReadAllText("data.txt");
// Read the shifted file
string shiftedText = File.ReadAllText("unshifted.txt");
// Check if the decrypted file is valid
return shiftedText == originalText;
}
Function IsShiftedFileValid() As Boolean
'Read the shifted file
Dim originalText As String = File.ReadAllText("data.txt")
'Read the shifted file
Dim shiftedText As String = File.ReadAllText("unshifted.txt")
'Check if the decrypted file is valid
Return shiftedText = originalText
End Function
Kode berikut menjalankan seluruh proses dekripsi enkripsi ini:
// Read the contents of data.txt, encrypt it, and write it to shifted.txt
WriteShiftedFile();
// Read the contents of shifted.txt, decrypt it, and write it to unshifted.txt
ReadShiftedFile();
// Check if the decrypted file is valid
Console.WriteLine(IsShiftedFileValid()
? "Decrypted file is valid" // True
: "Decrypted file is invalid" // False
);
// Output:
// Decrypted file is valid
Sub Main(args As String())
'Read the contents of data.txt, encrypt it, And write it to shifted.txt
WriteShiftedFile()
'Read the contents of shifted.txt, decrypt it, And write it to unshifted.txt
ReadShiftedFile()
'Check if the decrypted file Is valid
Console.WriteLine(IIf(IsShiftedFileValid(),
"Decrypted file is valid", ' True
"Decrypted file is invalid" ' False
))
End Sub
Kelas CipherStream
Cuplikan berikut menyediakan kelas CipherStream, yang menggunakan cipher shifting dasar untuk mengenkripsi dan mendekripsi byte. Kelas ini mewarisi dari Stream dan mendukung membaca atau menulis data.
Peringatan
Enkripsi yang digunakan dalam contoh ini dasar dan tidak aman. Ini tidak dimaksudkan untuk benar-benar mengenkripsi data untuk digunakan, tetapi disediakan untuk menunjukkan perubahan data melalui komposisi aliran.
using System.IO;
public class CipherStream : Stream
{
// WARNING: This is a simple encoding algorithm and should not be used in production code
const byte ENCODING_OFFSET = 80;
private bool _readable;
private bool _writable;
private Stream _wrappedBaseStream;
public override bool CanRead => _readable;
public override bool CanSeek => false;
public override bool CanWrite => _writable;
public override long Length => _wrappedBaseStream.Length;
public override long Position
{
get => _wrappedBaseStream.Position;
set => _wrappedBaseStream.Position = value;
}
public static CipherStream CreateForRead(Stream baseStream)
{
return new CipherStream(baseStream)
{
_readable = true,
_writable = false
};
}
public static CipherStream CreateForWrite(Stream baseStream)
{
return new CipherStream(baseStream)
{
_readable = false,
_writable = true
};
}
private CipherStream(Stream baseStream) =>
_wrappedBaseStream = baseStream;
public override int Read(byte[] buffer, int offset, int count)
{
if (!_readable) throw new NotSupportedException();
if (count == 0) return 0;
int returnCounter = 0;
for (int i = 0; i < count; i++)
{
int value = _wrappedBaseStream.ReadByte();
if (value == -1)
return returnCounter;
value += ENCODING_OFFSET;
if (value > byte.MaxValue)
value -= byte.MaxValue;
buffer[i + offset] = Convert.ToByte(value);
returnCounter++;
}
return returnCounter;
}
public override void Write(byte[] buffer, int offset, int count)
{
if (!_writable) throw new NotSupportedException();
byte[] newBuffer = new byte[count];
buffer.CopyTo(newBuffer, offset);
for (int i = 0; i < count; i++)
{
int value = newBuffer[i];
value -= ENCODING_OFFSET;
if (value < 0)
value = byte.MaxValue - value;
newBuffer[i] = Convert.ToByte(value);
}
_wrappedBaseStream.Write(newBuffer, 0, count);
}
public override void Flush() => _wrappedBaseStream.Flush();
public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
public override void SetLength(long value) => throw new NotSupportedException();
}
Imports System.IO
Public Class CipherStream
Inherits Stream
Const ENCODING_OFFSET As Byte = 80
Private _readable As Boolean = False
Private _writable As Boolean = False
Private _wrappedBaseStream As Stream
Public Overrides ReadOnly Property CanRead As Boolean
Get
Return _readable
End Get
End Property
Public Overrides ReadOnly Property CanSeek As Boolean
Get
Return False
End Get
End Property
Public Overrides ReadOnly Property CanWrite As Boolean
Get
Return _writable
End Get
End Property
Public Overrides ReadOnly Property Length As Long
Get
Return _wrappedBaseStream.Length
End Get
End Property
Public Overrides Property Position As Long
Get
Return _wrappedBaseStream.Position
End Get
Set(value As Long)
_wrappedBaseStream.Position = value
End Set
End Property
Public Shared Function CreateForRead(baseStream As Stream) As CipherStream
Return New CipherStream(baseStream) With
{
._readable = True,
._writable = False
}
End Function
Public Shared Function CreateForWrite(baseStream As Stream) As CipherStream
Return New CipherStream(baseStream) With
{
._readable = False,
._writable = True
}
End Function
Private Sub New(baseStream As Stream)
_wrappedBaseStream = baseStream
End Sub
Public Overrides Function Read(buffer() As Byte, offset As Integer, count As Integer) As Integer
If Not _readable Then Throw New NotSupportedException()
If count = 0 Then Return 0
Dim returnCounter As Integer = 0
For i = 0 To count - 1
Dim value As Integer = _wrappedBaseStream.ReadByte()
If (value = -1) Then Return returnCounter
value += ENCODING_OFFSET
If value > Byte.MaxValue Then
value -= Byte.MaxValue
End If
buffer(i + offset) = Convert.ToByte(value)
returnCounter += 1
Next
Return returnCounter
End Function
Public Overrides Sub Write(buffer() As Byte, offset As Integer, count As Integer)
If Not _writable Then Throw New NotSupportedException()
Dim newBuffer(count) As Byte
buffer.CopyTo(newBuffer, offset)
For i = 0 To count - 1
Dim value As Integer = newBuffer(i)
value -= ENCODING_OFFSET
If value < 0 Then
value = Byte.MaxValue - value
End If
newBuffer(i) = Convert.ToByte(value)
Next
_wrappedBaseStream.Write(newBuffer, 0, count)
End Sub
Public Overrides Sub Flush()
_wrappedBaseStream.Flush()
End Sub
Public Overrides Function Seek(offset As Long, origin As SeekOrigin) As Long
Throw New NotSupportedException()
End Function
Public Overrides Sub SetLength(value As Long)
Throw New NotSupportedException()
End Sub
End Class