Akış oluşturma
Yedekleme deposu, disk veya bellek gibi bir depolama ortamıdır. Her bir yedekleme deposu türü, sınıfının bir uygulaması Stream olarak kendi akışını uygular.
Her akış türü, verilen yedekleme deposundan ve içindeki baytları okur ve yazar. Yedekleme depolarına bağlanan akışlara temel akışlar adı verilir. Temel akışlar, akışı yedekleme deposuna bağlamak için gerekli parametrelere sahip oluşturuculara sahiptir. Örneğin, dosyanın kimden okunduğunu, FileStream yazıldığını veya her ikisini birden oluşturup oluşturmadığını belirleyen bir erişim modu parametresi belirten oluşturucuları vardır.
Sınıfların System.IO tasarımı basitleştirilmiş akış bileşimi sağlar. İstediğiniz işlevselliği sağlayan bir veya daha fazla geçiş akışına temel akışlar ekleyebilirsiniz. Tercih edilen türlerin kolayca okunabilmesi veya yazılabilmesi için, zincirin sonuna bir okuyucu veya yazıcı ekleyebilirsiniz.
Önkoşullar
Bu örneklerde data.txt adlı düz metin dosyası kullanılır. Bu dosyada metin bulunmalıdır.
Örnek: Akış verilerini şifreleme ve şifresini çözme
Aşağıdaki örnek bir dosyadaki verileri okur, şifreler ve ardından şifrelenmiş verileri başka bir dosyaya yazar. Akış oluşturma, temel bir kaydırma şifrelemesi kullanarak verileri dönüştürmek için kullanılır. Akıştan geçen her bayt değerini 80 değiştirmiştir.
Uyarı
Bu örnekte kullanılan şifreleme temel ve güvenli değildir. Aslında kullanım için verileri şifrelemek için tasarlanmamıştır, ancak akış oluşturma yoluyla verilerin değiştirilmesini göstermek için sağlanır.
Şifreleme için kaynak verileri okuma
Aşağıdaki kod bir dosyadaki metni okur, dönüştürür ve sonra başka bir dosyaya yazar.
İpucu
Bu kodu gözden geçirmeden önce, kullanıcı tanımlı bir tür olduğunu CipherStream
bilin. Bu sınıfın kodu, CipherStream sınıfı bölümünde sağlanır.
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
Önceki kodla ilgili aşağıdaki yönleri göz önünde bulundurun:
- İki FileStream nesne vardır:
- İlk
FileStream
(inputBaseStream
değişken) nesnesi data.txt dosyasının içeriğini okur. Bu, giriş veri akışıdır. - İkinci
FileStream
(outputBaseStream
değişken) nesnesi gelen verileri shifted.txt dosyasına yazar. Bu, çıkış veri akışıdır.
- İlk
CipherStream
(encryptStream
değişken) nesnesi, içinencryptStream
temel akışı yapaninputBaseStream
öğesini sarmalarinputBaseStream
.
Giriş akışı doğrudan veri akışından okunabilir ve çıkış akışına yazılabilir, ancak bu verileri dönüştürmez. Bunun yerine, encryptStream
verileri okumak için giriş akışı sarmalayıcısı kullanılır. verilerinden encryptStream
okundukça temel akıştan inputBaseStream
çeker, dönüştürür ve döndürür. Döndürülen veriler, verileri shifted.txt dosyasına yazan öğesine yazılıroutputBaseStream
.
Şifre çözme için dönüştürülen verileri okuma
Bu kod, önceki kod tarafından gerçekleştirilen şifrelemeyi tersine çevirir:
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
Önceki kodla ilgili aşağıdaki yönleri göz önünde bulundurun:
- İki FileStream nesne vardır:
- İlk
FileStream
(inputBaseStream
değişken) nesnesi shifted.txt dosyasının içeriğini okur. Bu, giriş veri akışıdır. - İkinci
FileStream
(outputBaseStream
değişken) nesnesi gelen verileri unshifted.txt dosyasına yazar. Bu, çıkış veri akışıdır.
- İlk
CipherStream
(unencryptStream
değişken) nesnesi, içinunencryptStream
temel akışı yapanoutputBaseStream
öğesini sarmalaroutputBaseStream
.
Burada kod önceki örnekten biraz farklıdır. Giriş akışını sarmalamak yerine çıkış unencryptStream
akışını sarmalar. Veriler giriş akışından inputBaseStream
okundukça çıkış akışı sarmalayıcısına unencryptStream
gönderilir. Veri aldığında unencryptStream
, verileri dönüştürür ve ardından temel akışa outputBaseStream
yazar. Çıkış outputBaseStream
akışı verileri unshifted.txt dosyasına yazar.
Dönüştürülen verileri doğrulama
Önceki iki örnek, veriler üzerinde iki işlem gerçekleştirdi. İlk olarak, data.txt dosyasının içeriği şifrelendi ve shifted.txt dosyasına kaydedildi. İkinci olarak, shifted.txt dosyasının şifrelenmiş içeriğinin şifresi çözülerek unshifted.txt dosyasına kaydedildi. Bu nedenle, data.txt dosyası ve unshifted.txt dosyası tam olarak aynı olmalıdır. Aşağıdaki kod bu dosyaları eşitlik için karşılaştırır:
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
Aşağıdaki kod bu şifre çözme işleminin tamamını çalıştırır:
// 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
CipherStream sınıfı
Aşağıdaki kod parçacığı, baytları CipherStream
şifrelemek ve şifresini çözmek için temel bir kaydırma şifrelemesi kullanan sınıfını sağlar. Bu sınıf, 'den Stream devralır ve veri okumayı veya yazmayı destekler.
Uyarı
Bu örnekte kullanılan şifreleme temel ve güvenli değildir. Aslında kullanım için verileri şifrelemek için tasarlanmamıştır, ancak akış oluşturma yoluyla verilerin değiştirilmesini göstermek için sağlanır.
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