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

 


Связанные темы