Aracılığıyla paylaş


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.
  • CipherStream (encryptStream değişken) nesnesi, için encryptStreamtemel akışı yapan inputBaseStream öğ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 encryptStreamokundukç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.
  • CipherStream (unencryptStream değişken) nesnesi, için unencryptStreamtemel akışı yapan outputBaseStream öğ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

Ayrıca bkz.