C#. Клас Stream. Методи (операції) пошуку в потоці

Клас Stream. Методи (операції) пошуку в потоці

Дана тема є продовженням наступних тем:


Зміст


Пошук на інших ресурсах:




1. Властивість CanSeek. Приклад

Властивість призначена для визначення того, чи поточний потік підтримує перемотування покажчика читання/запису файлу.
Згідно документації C# загальна форма властивості наступна

public abstract bool CanSeek { get; }

Приклад. У найбільш загальному випадку, процес перемотування покажчика методом Seek() виглядає так

...

using (FileStream fs = new FileStream("myfile.bin", ...))
{
  if (fs.CanSeek)
  {
    // Переміщення покажчика в методі Seek()
    fs.Seek(...);

    ...
  }
  else
  {
    Console.WriteLine(@"The stream doesn't support seeking.");
  }
    ...
}

 

2. Властивість Position. Приклад

Якщо ця властивість перевизначена у похідному класі, то з допомогою неї можна:

  • зчитати поточне значення покажчика читання/запису файлу;
  • встановити нове значення покажчика читання/запису.

Приклад. У фрагменті коду встановлюється нове значення покажчика читання файлу.

...

using (FileStream fWrite = new FileStream("myfile.bin", FileMode.Create, FileAccess.Write))
{
  ...

  // Встановити покажчик на кінець файлу - за останній байт у файлі
  fWrite.Position = fWrite.Length;

  // Встановити покажчик на початок файлу
  fWrite.Position = 0;

  ...
}

...

 

3. Метод SetLength(). Приклад

Якщо метод перевизначений в підкласі, то цей метод встановлює довжину поточного потоку. Загальна форма методу наступна:

public abstract void SetLength(long value)

тут value – значення, що визначає розмір потоку в байтах.

Щоб встановити новий розмір файлу (потоку), потрібно щоб файл підтримував запис.

Приклад. Нехай потрібно встановити розмір байтового файлу рівний 5000 байт. Для цього потрібно використати виклик:

...

using (FileStream fWrite = new FileStream("myfile.bin", FileMode.Create, FileAccess.Write))
{
  ...

  // Встановити розмір файлу 5000 байт
  fWrite.SetLength(5000);

  ...
}

...

 

4. Властивість Length. Приклад

Щоб визначити довжину файлу використовується властивість Length

public abstract long Length { get; }

Ця властивість є корисною, коли потрібно виділити пам’ять для байтового буферу типу byte[].

Приклад. Нехай потрібно зчитати з файлу рядок, який був попередньо записаний. Довжина рядка невідома. Фрагмент коду, що вирішує цю задачу з використанням властивості Length. Тут потрібно мати на увазі, що у файлі записаний тільки один рядок.

...

// Зчитування рядка з файлу
using (FileStream fRead = new FileStream("myfile.bin", FileMode.Open, FileAccess.Read))
{
  // Рядок, який буде отримано з файлу
  string str = "";

  // Буфер, де буде записано рядок
  byte[] strByte;

  // Виділити пам'ять для буфера - використати властивість Length
  strByte = new byte[fRead.Length];

  // Прочитати байти з файлу в буфер strByte
  int bt;

  for (int i = 0; i < fRead.Length; i++)
  {
    bt = fRead.ReadByte(); // зчитати байт з файлу
    str = str + (char)bt; // Додати до рядка символ bt
  }

  // Вивести рядок
  Console.WriteLine("str = " + str);
}
...

 

5. Метод Seek(). Приклад

Метод Seek() перемотує покажчик запису/читання у файлі на вказану кількість байт. Згідно з документацією загальна форма методу Seek() наступна

public abstract long Seek(long offset, System.IO.SeekOrigin origin)

тут

  • offset – зміщення в байтах, на яке потрібно перемотати покажчик;
  • origin – позиція, з якої потрібно починати виконувати зсув. Ця позиція визначається зчисленням SeekOrigin.

Зчислення SeekOrigin має наступні константи:

  • Begin – визначає початок потоку;
  • Current – визначає поточне значення покажчика в потоці. Переміщення покажчика (перемотування, зсув) відбувається з поточної позиції;
  • End – кінець потоку. Переміщення покажчика відбувається з кінця потоку.

Приклад. У прикладі у файл записуються три числа типу double. Потім друге та третє числа перезаписуються новими значеннями. У прикладі також продемонстровано можливості класу BitConverter.

using System;
using System.IO;

namespace ConsoleApp10
{
  class Program
  {
    static void Main(string[] args)
    {
      // Запис трьох чисел типу double у файл та перезапис другого числа
      using (FileStream fWrite = new FileStream("myfile.bin", FileMode.Create, FileAccess.Write))
      {
        // задано 3 числа типу double
        double x1 = 2.88;
        double x2 = 1.77;
        double x3 = -220.345;

        // масив байтів, який буде безпосередньо записаний у файл
        byte[] AB = new byte[sizeof(double)]; // виділити пам'ять для розміру типу double

        // записати число x1
        AB = BitConverter.GetBytes(x1);
        fWrite.Write(AB, 0, AB.Length); // записати число - метод Write

        // записати число x2
        AB = BitConverter.GetBytes(x2);
        fWrite.Write(AB, 0, AB.Length);

        // записати число x3
        AB = BitConverter.GetBytes(x3);
        fWrite.Write(AB, 0, AB.Length);

        // Перезаписати число x2 іншим значенням - використати метод Seek()
        fWrite.Seek(sizeof(double), SeekOrigin.Begin); // зсув на 1 число від початку
        AB = BitConverter.GetBytes(55.78); // число 55.78 буде новим замість x2
        fWrite.Write(AB, 0, AB.Length);

        // Перезаписати число x3 іншим значенням - використати зсув від кінця файлу
        // Важливо: значення offset - від'ємне.
        fWrite.Seek(-sizeof(double), SeekOrigin.End);
        AB = BitConverter.GetBytes(22.33);
        fWrite.Write(AB, 0, AB.Length);
      }

      // Зчитування рядка з файлу
      using (FileStream fRead = new FileStream("myfile.bin", FileMode.Open, FileAccess.Read))
      {
        // Числа, які будуть отримані з файлу
        double x1, x2, x3;

        // Буфер, де буде записано числа
        byte[] array = new byte[fRead.Length];

        // Прочитати байти з файлу в буфер array
        fRead.Read(array, 0, array.Length);

        // Отримати з буферу перше число
        x1 = BitConverter.ToDouble(array, 0);

        // Отримати з буферу друге число
        x2 = BitConverter.ToDouble(array, sizeof(double));

        // Отримати з буферу третє число
        x3 = BitConverter.ToDouble(array, 2 * sizeof(double));

        // Вивести числа
        Console.WriteLine("x1 = {0:f}", x1);
        Console.WriteLine("x2 = {0:f}", x2);
        Console.WriteLine("x3 = {0:f}", x3);
      }
    }
  }
}

Результат виконання програми

x1 = 2.88
x2 = 55.78
x3 = 22.33

 


 Зв’язані теми