close

Вход

Забыли?

вход по аккаунту

?

Программирование. Курсовая работа. Семестр 3.

код для вставкиСкачать
МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ
НОВОСИБИРСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСТИЕТ
Курсовая работа
по дисциплине "Программирование"
Группа: АБ-121
Студент: Дик Максим (вариант 5.2)
Преподаватель: Молявко А.А.
НОВОСИБИРСК 2012
Оглавление
1. Описание задания................................................................................................3
2. Структурное описание разработки..........................................................................3
3. Функциональное описание разработки....................................................................8
4. Описание интерфейса программы.........................................................................22
5. Контрольные примеры.......................................................................................22
6. Выводы............................................................................................................23
7. Список использованной литературы.....................................................................24
8. Приложение .....................................................................................................25
1) Описание задания.
Шаблон - двоичный файл, содержащий односвязный список объектов. Тип хранимого в файле объекта - параметр шаблона. В начале файла расположен файловый указатель на первый элемент списка. Элемент списка содержит файловый указатель на следующий элемент, за которым следует объект. Класс двоичного файла, производный от FileStream. Двоичный файл содержит заданную структуру данных с типом хранимых объектов - параметром шаблона. Программа должна выполнять операции создания файла, просмотра, добавления, удаления, обновления и сортировки объектов заданного при генерации типа. Реализовать две версии программы для различных хранимых объектов (например, текстовых строк и объектов класса из лабораторной работы). Предполагается, что для заданной структуры данных реализован метод CompareTo.
Для позиционирования в потоке можно использовать методы seek(long,mode). Запись и чтение объекта осуществляется при помощи методов Serialize(), Deserialize().
Программа должна реализовывать указанные выше действия. Протестировать структуру данных на простом типе данных (например, int, double и т.д.) и сложном. Программа тестирования должна содержать меню, обеспечивающее выбор операций.
2) Структурное описание разработки.
Для реализации поставленной задачи был создан новый шаблонный класс "newFile".
Класс newFile наследован от класса "FileStream".
Структура файла: Некоторые классы и методы, использованные при написании программы:
1) FileStream - класс - Предоставляет Stream в файле, поддерживая синхронные и асинхронные операции чтения и записи. В программе использован конструктор FileStream (String, FileMode)
public FileStream (string path, FileMode mode), где path Тип: System .String - Абсолютный или относительный путь к файлу, который инкапсулируется текущим объектом FileStream.
mode
Тип: System.IO .FileMode - - перечисление - Описывает, каким образом операционная система должна открывать файл.
Члены перечисления System.IO .FileMode:
Имя члена Описание CreateNewУказывает, что операционная система должна создавать новый файл. CreateУказывает, что операционная система должна создавать новый файл.
Если файл уже существует, он будет переписан. OpenУказывает, что операционная система должна открыть существующий файл.
Если данный файл не существует, создается OpenOrCreateУказывает, что операционная система должна открыть файл, если он существует, в противном случае должен быть создан новый файл. TruncateУказывает, что операционная система должна открыть существующий файл.
После открытия должно быть выполнено усечение файла таким образом, чтобы его размер стал равен нулю. AppendОткрывает файл, если он существует, и находит конец файла; либо создает новый файл.
Класс FileStream используется для операций чтения и записи в файл, открытия и закрытия файлов в файловой системе, а также для изменения других дескрипторов операционной системы для обработки файлов, включая каналы, стандартный ввод и вывод.
Для операций чтения и записи можно задать либо синхронный, либо асинхронный режим.
FileStream буферизует ввод и вывод для лучшей производительности.
Объекты FileStream поддерживают произвольный доступ к файлам с помощью метода Seek. FileStream .Seek - метод - Устанавливает текущее положение этого потока на заданное значение. Seek позволяет перемещать положение позиции чтения записи в файле. Это осуществляется путем смещения параметров точки ссылки.
Смещение в байтах относительно точки ссылки поиска, которая может располагаться в начале, в текущем положении или в конце файла, определяется тремя свойствами класса SeekOrigin. SeekOrigin - перечисление - Предоставляет поля, представляющие точки ссылки для поиска в потоках.
Имя члена Описание Begin Задает начало потока. CurrentЗадает текущее положение в потоке. End Задает конец потока.Также в программе неоднократно используется свойство Length.
FileStream .Length - свойство - Получает длину потока в байтах.
2) File - класс - Предоставляет статические методы для создания, копирования, удаления, перемещения и открытия файлов, а также помогает при создании объектов FileStream.
File .Delete - метод - Удаляет указанный файл.
public static void Delete ( string path), где path - Тип: System .String - Имя файла, предназначенного для удаления. 3) FileInfo - класс - Предоставляет свойства и методы экземпляра для создания, копирования, удаления, перемещения и открытия файлов, а также позволяет создавать объекты FileStream.
Этот класс не наследуется.
Используемый конструктор: FileInfo(string) - Выполняет инициализацию нового экземпляра класса FileInfo, выполняющего роль оболочки для пути файла.
public FileInfo(string fileName), где filename - Тип: System .String - Полное имя нового файла или относительное имя файла. Путь не должен заканчиваться символом разделителя каталогов.
FileInfo .MoveTo - метод - Перемещает заданный файл в новое местоположение и разрешает переименование файла.
public void MoveTo(string destFileName), где destFileName - Тип: System .String -Путь, указывающий на местоположение, в которое необходимо переместить файл; в этом же пути можно задать и другое имя файла.
4) BinaryFormatter - Сериализует и десериализует объект или весь граф связанных объектов в двоичном формате. Используемый конструктор: BinaryFormatter() - Инициализирует новый экземпляр BinaryFormatter значениями по умолчанию
BinaryFormatter .Serialize - метод (Stream, Object) - Сериализует объект или граф объектов с указанной вершиной (корнем) в заданный поток.
BinaryFormatter .Deserialize - метод (Stream) - Десериализует заданный поток в граф объекта.
5) BinaryReader - класс - Считывает простые типы данных как двоичные значения в заданной кодировке. Используемый конструктор BinaryReader (Stream) - Выполняет инициализацию нового экземпляра класса BinaryReader на базе предоставленного потока с использованием UTF8Encoding BinaryReader .ReadInt64 - метод - Считывает целое число со знаком длиной 8 байта из текущего потока и перемещает текущую позицию в потоке на восемь байтов вперед. Метод не восстанавливает позицию файла после невыполненной операции чтения. BinaryReader считывает данные этого типа в формате с прямым порядком байтов.
6) BinaryWriter - класс - Записывает простые типы данных в поток как двоичные значения и поддерживает запись строк в определенной кодировке.
Используемый конструктор BinaryWriter (Stream) - Выполняет инициализацию нового экземпляра класса BinaryWriter на основе соответствующего потока, использующего для кодирования строк кодировку UTF-8.
BinaryWriter .Write - метод (Int64) - Записывает целое число со знаком длиной 8 байт в текущий поток и перемещает позицию в потоке вперед на восемь байт. Метод сохраняет данные этого типа в формате с прямым порядком байтов.
7) На параметр T накладывается ограничение наследования, т.е. тип T должен являться наследником интерфейса IComparable.
IComparable <T> - интерфейс - Определяет обобщенный метод сравнения, тип значения или класс которого используется для создания метода сравнения упорядоченных экземпляров.
IComparable <T>.CompareTo - метод сравнивает текущий объект с другим объектом того же типа.
Возвращаемое значение - Тип: System .Int32 - Значение, указывающее, каков относительный порядок сравниваемых объектов.
Расшифровка возвращенных значений приведена ниже.
Значение ЗначениеМеньше нуляЗначение этого объекта меньше значения параметра other.НульЗначение этого объекта равно значению параметра other.Больше нуля.Значение этого объекта больше значения параметра other.
Метод CompareTo предоставляет строго типизированный метод сравнения, который применяется для упорядочивания элементов объекта универсальной коллекции.
Описание класса newFile
class newFile<T> : FileStream where T : IComparable<T>
{...}
Класс newFile, производный от FileStream, содержит:
* один конструктор:
public newFile(string path, FileMode mode): base(path, mode)
* два закрытых поля, одно из них статическое:
//Полное имя файла
static string fileName;
//количество объектов в файле
long amount = 0;
* одно метод-свойство для поля amount, реализующее стратегию доступа к полю - только чтение (Read-only):
public long Amount {...}
* один индексатор, реализующий чтение и запись объектов типа T:
public T this[long index] {...}
* девять методов:
1) Метод добавления в конец файл:
public void Add(T exp)
{...}
Вызывает метод Add(exp, amount).
2) Метод добавления объекта по номеру:
public void Add(T exp, long number)
{...}
Если номер объекта больше, чем количество объектов в файле, то объект добавляется, как последний.
Если номер меньше нуля, то метод ничего не добавляет.
Если номер больше, либо равен, нулю и меньше, чем количество объектов в файле, то объект, заменяет другой объект соответствующий этому же номеру.
3) Метод добавления после объекта:
public void AddAfter(T exp, long number)
{...}
Если номер больше, чем количество объектов в файле, то вызывается метод Add(exp, amount).
4) Метод чтения объекта по номеру:
public T Read(long number)
{...}
Если номер больше, либо равен amount, то метод возвращает default(T), так как нумерации начинается с нуля, то есть индекс последнего элемента равен amount - 1.
5) Метод чтения объекта по номеру:
public void Read(ref T exp, long number)
{...}
6) Сортировка по возрастанию:
public void Sorting()
{...}
Сортирует объекты, для сравнения используется метод CompareTo. Перезапись объектов не происходит, объекты меняются местами за счет изменения указателей.
7) Метод удаление объекта:
public void DeleteNode(long number)
{...}
Удаление объекта из файла не происходит, меняется лишь указатель предыдущего элемента.
8) Обновление:
public void Update()
{...}
Происходит запись объектов в новый файл temp по порядку, затем происходит удаление текущего файла методом File.Delete(fileName) и переименование tepm в filename:
FileInfo fi = new FileInfo("temp.bin");
fi.MoveTo(fileName);
9) Метод удаления файла:
public void delete()
{...}
Методом File.Delete(fileName) происходит удаление.
3) Функциональное описание.
Конструктор класса newFile
public newFile(string path, FileMode mode) : base(path, mode)
{...}
Алгоритм:
1) Полю filename присваивается значение строки path.
2) Объявляется переменная nextExp типа long, и ей присваивается значение 0.
3) Если файл пустой (this.Length == 0), то в начало файла записывается указатель равный нулю: amount = 0;
nextExp = 0;
BinaryWriter binWriter = new BinaryWriter(this);
binWriter.Write(nextExp);
binWriter.Close();
Иначе производится подсчет объектов в файле:
amount = 0;
BinaryReader binReader = new BinaryReader(this);
//Считывается ссылка на 0 элемент
nextExp = binReader.ReadInt64();
//Устанавливаем текущее положение этого потока на 0 элемент
this.Seek(nextExp, SeekOrigin.Begin);
//Если ссылка на 0 элемент не равно нулю, то производим подсчет объектов
if (nextExp != 0)
for (long pos = 0; pos < this.Length; pos = System.Convert.ToInt64(this.Position))
{
nextExp = binReader.ReadInt64();
this.Seek(nextExp, SeekOrigin.Begin);
amount++;
}
binReader.Close();
1) Файл закрывается.
Индексатор
public T this[long index]
{
get
{
//Если индекс меньше нуля или больше, чем количество элементов в файле, то
//вернуть default(T)
if (index < 0 || index >= amount)
return default(T);
//Иначе вызвать метод Read
else
return Read(index);
}
set
{
Add(value, index);
}
}
Метод добавления объекта по номеру
public void Add(T exp, long number)
{...}
Алгоритм:
1) Проверка.
Если number меньше нуля, то завершить выполнение функции.
Если number больше, чем количество элементов в файле, то number присвоить значение amount.
2) Объявление и инициализация объектов:
long nextExp = 0;
//Порядковый номер элемента
long value = 0;
//Индекс на nextExp предыдущего объекта
long previousIndexNextExp = 0;
//Индекс на nextExp текущего объекта
long currentIndexNextExp = 0;
BinaryFormatter bf = new BinaryFormatter();
FileStream fs;
//открываем файл
fs = new FileStream(fileName, FileMode.Open);
BinaryWriter binWriter = new BinaryWriter(fs);
BinaryReader binReader = new BinaryReader(fs);
3) Если количество элементов в файле равно нулю, то amount присваивается значение 1, в начало файла записывается указатель равный fs.Length, и в конец файла записывается объект с указателем на конец файла. Выполнение методы завершается. 4) Если number меньше чем amount, то осуществляем поиск элемента соответствующего номеру number и замена его на exp и завершаем выполнение метода.
fs.Seek(0, SeekOrigin.Begin);
nextExp = binReader.ReadInt64();
//Устанавливает текущее положение на 0 элемент
fs.Seek(nextExp, SeekOrigin.Begin);
//Запоминаем позицию
currentIndexNextExp = nextExp;
if (number < amount)
for (value = 0; value < amount; value++)//&& p != fs.Length
{
//Считываем указатель на 1 элемент
nextExp = binReader.ReadInt64();
//Если номер элемента соответствует number, то произвести замену элемента //на //exp
if (value == number)
{
//Устанавливает текущее положение на nextExp предыдущего объекта
fs.Seek (previousIndexNextExp, SeekOrigin.Begin);
//Записываем указатель на конец файла
binWriter.Write(fs.Length);
//Устанавливает текущее положение в конец
fs.Seek(0, SeekOrigin.End);
//Запоминаем текущую позицию
long tempEnd = System.Convert.ToInt64(fs.Position);
//Записываем указатель на следующий элемент
binWriter.Write (nextExp);
//Запись объекта
bf.Serialize (fs, exp);
// Устанавливает текущее положение на nextExp следующего объекта
fs.Seek (nextExp, SeekOrigin.Begin);
//Производим поиск последнего элемента
PreviousIndexNextExp = nextExp;
while (nextExp != tempEnd)
{
previousIndexNextExp = nextExp;
nextExp = binReader.ReadInt64 ();
fs.Seek (nextExp, SeekOrigin.Begin);
}
//Меняем указатель последнего элемента на fs.Length
fs.Seek (previousIndexNextExp, SeekOrigin.Begin);
binWriter.Write (fs.Length);
binWriter.Close ();
binReader.Close ();
fs.Close ();
//Прекращаем выполнение метода
return;
}
//Устанавливает текущее положение на nextExp
fs.Seek (nextExp, SeekOrigin.Begin);
previousIndexNextExp = currentIndexNextExp;
currentIndexNextExp = nextExp;
}
5) Записываем объект в конец файла, как последний элемент:
//Устанавливает текущее положение в конец
fs.Seek(0, SeekOrigin.End);
//Запоминаем позицию для записи nextExp
long indexNextExp = System.Convert.ToInt32(fs.Position);
//Занимаем место под nextExp
binWriter.Write (nextExp);
//Запись объекта
bf.Serialize (fs, exp);
//Запоминаем позицию, куда будет записан следующий элемент
nextExp = System.Convert.ToInt32 (fs.Position);
//Устанавливает текущее положение на nextExp
fs.Seek (indexNextExp, SeekOrigin.Begin);
binWriter.Write(nextExp);
binWriter.Close();
binReader.Close();
fs.Close();
amount++;
Метод добавления после объекта
public void AddAfter(T exp, long number)
{...}
Метод добавляет объект, после объекта под номером number.
Алгоритм: 1)Проверка. Если количество объектов в файле равно нулю, то завершить выполнение метода.
Если number меньше нуля, то выполнение метода прекращается. Если number больше, либо равен, количеству элементов, то вызвать метод Add(exp, amount) и завершить выполнение метода.
//Если количество объектов в файле равно нулю, завершить выполнение метода
if (amount == 0)
return;
//Если номер меньше нуля, завершить выполнение метода
if (number < 0)
return;
//Если номер больше либо равен количеству объектов в файле вызвать метод
//Add(exp, amount);
if (number >= amount)
{
Add(exp, amount);
return;
}
2) Объявление и инициализация объектов: long nextExp = 0;
//Порядковый номер элемента
long value = 0;
//Индекс на nextExp предыдущего объекта
long previousIndexNextExp = 0;
//Индекс на nextExp текущего объекта
long currentIndexNextExp = 0;
BinaryFormatter bf = new BinaryFormatter();
FileStream fs;
fs = new FileStream(fileName, FileMode.Open);
BinaryWriter binWriter = new BinaryWriter(fs);
BinaryReader binReader = new BinaryReader(fs);
3) Поиск элемента, на место которого будет вставлен объект exp, и вставка элемента.
//Устанавливает текущее положение на начало файла fs.Seek(0, SeekOrigin.Begin);
//Указатель на нулевой элемент
nextExp = binReader.ReadInt64();
//Устанавливает текущее положение на нулевой элемент
fs.Seek(nextExp, SeekOrigin.Begin);
//Запоминаем значение nextExp
currentIndexNextExp = nextExp;
while (true)
{
//Считываем указатель на следующий элемент
nextExp = binReader.ReadInt64();
//Если value равен number+1 осуществить вставку элемента
if (number == value - 1)
{
//Устанавливает текущее положение на nextExp предыдущего объекта (value //-1)
fs.Seek(previousIndexNextExp, SeekOrigin.Begin);
//Запоминаем указатель на следующий элемент (value)
long temp = binReader.ReadInt64();
//Устанавливает текущее положение на nextExp предыдущего объекта (value -1)
fs.Seek(previousIndexNextExp, SeekOrigin.Begin);
//Записываем указатель на конец файла
binWriter.Write(fs.Length);
//nextExp присваиваем значение указателя на следующий элемент
nextExp = temp;
//Устанавливает текущее положение в конец файла
fs.Seek(0, SeekOrigin.End);
//Запоминаем позицию
long tempEnd = System.Convert.ToInt64(fs.Position);//Получаем //Записываем указатель на элемент value
binWriter.Write(nextExp);
//Запись объекта
bf.Serialize(fs, exp);
//Поиск последнего элемента и изменение его указателя
fs.Seek(nextExp, SeekOrigin.Begin);
temp = binReader.ReadInt64();
if (temp == tempEnd)
{
fs.Seek(nextExp, SeekOrigin.Begin);
binWriter.Write(fs.Length);
}
else
{
previousIndexNextExp = nextExp;
fs.Seek(nextExp, SeekOrigin.Begin);
while (nextExp != tempEnd)
{
previousIndexNextExp = nextExp;
nextExp = binReader.ReadInt64();
fs.Seek(nextExp, SeekOrigin.Begin);
}
fs.Seek(previousIndexNextExp, SeekOrigin.Begin);
binWriter.Write(fs.Length);
}
binWriter.Close();
binReader.Close();
amount++;
fs.Close();
return;
}
fs.Seek(nextExp, SeekOrigin.Begin); previousIndexNextExp = currentIndexNextExp;
currentIndexNextExp = nextExp;
value++;
}
Метод чтения объекта по номеру
public T Read(long number)
{...}
Метод возвращает объект типа T.
Алгоритм:
1. Проверка.
Если number меньше нуля или больше, либо равен amount, то вернуть default(T):
if (number < 0 || number >= amount)
return default(T);
2. Объявление и инициализация объектов:
T exp = default(T);
long pos = 0;
long nextExp = 0;
long previousIndexNextExp = 0;
long value = 0;
BinaryFormatter bf = new BinaryFormatter();
FileStream fs = new FileStream(fileName, FileMode.Open);
BinaryReader binReader = new BinaryReader(fs);
3. Осуществляем поиск элемента, соответствующего номеру number, и возвращаем этот элемент:
//Устанавливаем текущее положение на начало файла
fs.Seek(0, SeekOrigin.Begin);
//Считываем указатель на нулевой элемент
nextExp = binReader.ReadInt64();
//Устанавливаем текущее положение на нулевой элемент
fs.Seek(nextExp, SeekOrigin.Begin);
while (pos != fs.Length)
{
//Запоминаем указатель на текущий элемент
previousIndexNextExp = nextExp;
//Считываем указатель на следуюзий элемент
nextExp = binReader.ReadInt64();
//Если номер элемента соответствует number, то считать элемент и вернуть его
if (number == value)
{
exp = (T)bf.Deserialize(fs);
binReader.Close();
fs.Close();
return exp;
}
//Устанавливает текущее положение на следующий элемент
fs.Seek(nextExp, SeekOrigin.Begin);//Перемещаем указатель на nextExp
//Считываем текущее положение
pos = System.Convert.ToInt64(fs.Position);
value++;
}
binReader.Close();
fs.Close();
return default(T);
Сортировка
public void Sorting()
{...}
Сравнение объектов между собой осуществляется при помощи метода CompareTo.
Для сортировки используется метод пузырька, которым обычно сортируются массивы:
Элементы меняются местами, путем изменения их указателей.
Алгоритм:
1) Объявление и инициализация объектов:
BinaryFormatter bf = new BinaryFormatter();
FileStream fs = new FileStream(fileName, FileMode.Open);
BinaryWriter binWriter = new BinaryWriter(fs);
BinaryReader binReader = new BinaryReader(fs);
T min = default(T);
T temp = default(T);
//Объект exp будет использоваться, для того чтобы поменять местами объекты min и temp
T exp = default(T);
//Для объекта min
//Положение указателя прошлого элемента
long indexPreviousMinNextExp = 0;
//Положение указателя текущего элемента
long indexMinNextExp = 0;
//Указатель на следующий элемент
long minNextExp = 0;
//Для объекта temp
//Положение указателя прошлого элемента
long indexPreviousTempNextExp = 0;
//Положение указателя текущего элемента
long indexTempNextExp = 0;
//Указатель на следующий элемент
long tempNextExp = 0;
2) Сортировка элементов:
//Устанавливает текущее положение на начало
fs.Seek(0, SeekOrigin.Begin);
//Считываем указатель на нулевой элемент
minNextExp = binReader.ReadInt64();
//Для сортировки используем метод пузырька
for (int i = 1; i < amount; i++)
{
//Запоминаем указатель на текущий элемент
indexMinNextExp = minNextExp;
//Устанавливает текущее положение на слелующий элемент
fs.Seek(minNextExp, SeekOrigin.Begin); //Считываем указатель на следующий элемент
minNextExp = binReader.ReadInt64();
//Десериализуем объект
min = (T)bf.Deserialize(fs);
indexPreviousTempNextExp = indexMinNextExp;
indexTempNextExp = minNextExp;
for (int j = i; j < amount && indexTempNextExp != fs.Length; j++)
{
//Перемещаем указатель на nextExp fs.Seek(indexTempNextExp, SeekOrigin.Begin);
//Считываем указатель на следующий элемент
tempNextExp = binReader.ReadInt64();
//Считываем объект
temp = (T)bf.Deserialize(fs);
//Сравниваем min и exp
if (min.CompareTo(temp) > 0)
{
//Меняем местами объекты min и exp
//Изменить предыдущей min указатель на указатель на temp
fs.Seek(indexPreviousMinNextExp, SeekOrigin.Begin);
binWriter.Write(indexTempNextExp);
//Изменить указатель temp на указатель minNextExp
if (indexTempNextExp == minNextExp)
{
minNextExp = indexPreviousTempNextExp;
}
fs.Seek(indexTempNextExp, SeekOrigin.Begin);
binWriter.Write(minNextExp);
//Изменить предыдущей temp указатель на указатель на min
fs.Seek(indexPreviousTempNextExp, SeekOrigin.Begin);
binWriter.Write(indexMinNextExp);
//Изменить указатель min на указатель tempNextExp
fs.Seek(indexMinNextExp, SeekOrigin.Begin);
binWriter.Write(tempNextExp);
long position = indexMinNextExp;
indexMinNextExp = indexTempNextExp;
indexPreviousTempNextExp = position;
indexTempNextExp = tempNextExp;
exp = min;
min = temp;
temp = exp;
continue;
}
indexPreviousTempNextExp = indexTempNextExp;
indexTempNextExp = tempNextExp;
}
indexPreviousMinNextExp = indexMinNextExp;
}
binReader.Close();
binWriter.Close();
fs.Close();
Метод удаление объекта
public void DeleteNode(long number)
{...}
Удаление элемента осуществляется за счет изменения указателя предыдущего элемента.
Алгоритм:
1) Проверка.
Если number меньше нуля или больше, либо равен amount, то завершить выполнение метода:
//Проверка
if (number < 0 || number >= amount)
return;
2) Объявление и инициализация объектов:
long nextExp = 0;
//Порядковый номер элемента
long value = 0;
//Положение указателя предыдущего элемента
long previousIndexNextExp = 0;
//Положение указателя текущего элемента
long currentIndexNextExp = 0;
BinaryFormatter bf = new BinaryFormatter();
FileStream fs;
fs = new FileStream(fileName, FileMode.Open);//открываем файл
BinaryWriter binWriter = new BinaryWriter(fs);
BinaryReader binReader = new BinaryReader(fs);
3) Удаление объекта:
//Устанавливаем текущее положение на начало
fs.Seek(0, SeekOrigin.Begin);
//Считываем указатель на нулевой элемент
nextExp = binReader.ReadInt64();
//Запоминаем указатель на нулевой элемент
currentIndexNextExp = nextExp;
//Устанавливаем текущее положение на элемент первый элемент
fs.Seek(nextExp, SeekOrigin.Begin);
for (long i = 0; i < amount; i++)//&& pos != fs.Length
{
//Считываем указатель на следующий элемент
nextExp = binReader.ReadInt64();
//Если номер элемента соответствует number, то изменить указатель предыдущего элемента
if (value == number)
{
//Устанавливаем текущее положение на указатель предыдущего элемента
fs.Seek(previousIndexNextExp, SeekOrigin.Begin);
//Записываем указатель на следующий элемент
binWriter.Write(nextExp);
amount--;
binWriter.Close();
binReader.Close();
fs.Close();
return;
}
//Устанавливаем текущее положение на указатель следующего элемента
fs.Seek(nextExp, SeekOrigin.Begin);
previousIndexNextExp = currentIndexNextExp;
currentIndexNextExp = nextExp;
value++;
}
binWriter.Close();
binReader.Close();
fs.Close();
Обновление
public void Update()
{...}
Алгоритм:
1) Объявление и инициализация объектов:
BinaryFormatter bf = new BinaryFormatter();
FileStream fs = new FileStream(fileName, FileMode.Open);
FileStream temp = new FileStream("temp.bin", FileMode.Create);
BinaryWriter binWriter = new BinaryWriter(temp);
BinaryReader binReader = new BinaryReader(fs);
long nextExp = 0; long indexNextExp = 0;
T exp;
2) Проверка:
if (nextExp == 0)
{
//Если указатель на нулевой элемент равено 0, то записать в файл temp указатель равный 0
//Переименовать temp в fileName, и затем удалить fileName
//После чего завершить выполнение метода
binWriter.Write((long)0);
binWriter.Close();
binReader.Close();
fs.Close();
File.Delete(fileName);//Удаляем файл fileName
//Переименовываем temp.bin в fileName
FileInfo fi = new FileInfo("temp.bin");
fi.MoveTo(fileName);
return;
}
3) Переписываем объекты из файла fileName в temp.bin
//Устанавливаем текущее положение на нулевой элемент
fs.Seek(nextExp, SeekOrigin.Begin);
//Записываем в файл temp указатель на нулевой элемень
binWriter.Write((long)sizeof(long));
for (long i = 0; i < amount; i++)//&& pos != fs.Length
{
//Считываем указатель на следующий элемент
nextExp = binReader.ReadInt64();
//Десериализуем объект
exp = (T)bf.Deserialize(fs);
//Устанавливаем текущее положение на следующий элемент
fs.Seek(nextExp, SeekOrigin.Begin);
//Запоминаем текущее положение в файле temp
indexNextExp = System.Convert.ToInt64(temp.Position);
//Занимаем место под nextExp
binWriter.Write(nextExp);
//Сериализуем объект
bf.Serialize(temp, exp);
//Запоминаем позицию, куда будет записан следующий элемент
nextExp = System.Convert.ToInt32(temp.Position);
//Устанавливаем текущее положение indexNextExp
temp.Seek(indexNextExp, SeekOrigin.Begin);
//Записываем указатель на следующий элемент
binWriter.Write(nextExp);
//Устанавливаем текущее положение в файле temp на конец
temp.Seek(0, SeekOrigin.End);
}
binWriter.Close();
binReader.Close();
fs.Close();
4) Удаляем файл fileName
//Удаляем файл fileName
File.Delete(fileName);
5) Переименовываем temp.bin в fileName
//Переименовываем temp.bin в fileName
FileInfo fI = new FileInfo("temp.bin");
fI.MoveTo(fileName);
Метод удаления файла
Для удаления файла используется статический метод класса File:
public void delete()
{
//Закрыть файл
this.Close();
//Удалить файл
File.Delete(fileName);
}
4) Описание пользовательского интерфейса.
После запуска программы в консоль выводится сообщение об использование FileMode.OpenOrCreate при создании объекта класса newFile, а также что если файл не существует, то он будет создан.
Затем пользователю предлагается ввести полное имя файла.
После чего выводятся сообщения:
"Если объект типа string, то нажмите S
Если объект типа date, то нажмите D
Для выхода из программы выбора нажмите Escape"
После нажатия клавиш S или D, пользователю выводится сообщение об выбранном типе данных и о количестве объектов в файле, а также меню:
5. Контрольные примеры
Для проверки скорости выполнения операций, создадим список целочисленных элементов типа int. Скоростные показатели оказались следующими:
Как мы можем увидеть, уже с одной тысячью элементов сортировка выполняется очень долго - о себе дают знать медленные алгоритм сортировки и использование памяти жёсткого диска вместо оперативной памяти.
6. Выводы
В результате проведённой работы был разработан шаблонный класс newFile, хранящий свои элементы в двоичном файле. Работа с файлом происходит в бинарном режиме. Плюсы подхода: память, отводимая под список, ограничивается пространством жёсткого диска, а не оперативной памятью. Со списком легко возобновить работу, так как все данные хранятся в файле.
Минусы: низкая производительность по сравнению с аналогичным списком, работающим с оперативной памятью. Неэффективный алгоритм сортировки - не рассчитан на большое число элементов списка. Возможность появления областей памяти, занимающих место на жёстком диске, но которые нельзя использовать - проблему приходится решать с помощью отдельного метода, делающего файл более компактным.
7. Список использованной литературы
1) http://msdn.microsoft.com Дата работы с ресурсом:07.01.2013
8. Приложение
newFile.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace course_work
{
class newFile<T> : FileStream where T : IComparable<T>
{
//Полное имя файла
static string fileName;
//количество объектов в файле
long amount = 0;
//стратегия: Read-only для поля amount
public long Amount
{
get
{
return amount;
}
}
//Контсруктор
public newFile(string path, FileMode mode)
: base(path, mode)
{
fileName = path;
long nextExp = 0;
//Если файл пустой, то указатель на 0 элемент равено нулю
if (this.Length == 0)
{
amount = 0;
nextExp = 0;
BinaryWriter binWriter = new BinaryWriter(this);
binWriter.Write(nextExp);
binWriter.Close();
}
//Иначе производится подсчет количества объектов типа T в файле
else
{
amount = 0;
BinaryReader binReader = new BinaryReader(this);
//Считывается ссылка на 0 элемент
nextExp = binReader.ReadInt64();
//Устанавливаем текущее положение этого потока на 0 элемент
this.Seek(nextExp, SeekOrigin.Begin);
//Если ссылка на 0 элемент не равно нулю, то производим подсчет объектов
if (nextExp != 0)
for (long pos = 0; pos < this.Length; pos = System.Convert.ToInt64(this.Position))
{
nextExp = binReader.ReadInt64();
this.Seek(nextExp, SeekOrigin.Begin);
amount++;
}
binReader.Close();
}
this.Close();
}
//Индексатор
public T this[long index]
{
get
{
//Если индекс меньше нуля или больше, чем количество элементов в файле, то вернуть default(T)
if (index < 0 || index >= amount)
return default(T);
//Иначе вызвать метод Read
else
return Read(index);
}
set
{
Add(value, index);
}
}
//Метод добавления в конец файла
public void Add(T exp)
{
this.Add(exp, amount);
}
//Метод добавления объекта по номеру
public void Add(T exp, long number)
{
if (number < 0)
return;
if (number > amount)
number = amount;
// long p = 0;
long nextExp = 0;
//Порядковый номер элемента
long value = 0;
//Индекс на nextExp предыдущего объекта
long previousIndexNextExp = 0;
//Индекс на nextExp текущего объекта
long currentIndexNextExp = 0;
BinaryFormatter bf = new BinaryFormatter();
FileStream fs;
//открываем файл
fs = new FileStream(fileName, FileMode.Open);
BinaryWriter binWriter = new BinaryWriter(fs);
BinaryReader binReader = new BinaryReader(fs);
// //Если в файле нет ни одного объекта
if (amount == 0)
{
amount = 1;
fs.Seek(0, SeekOrigin.Begin);
binWriter.Write(fs.Length);
fs.Seek(0, SeekOrigin.End);
//Запоминаем позицию для записи nextExp
long pos = System.Convert.ToInt32(fs.Position);
//Занимаем место под nextExp
binWriter.Write(nextExp);
//Запись объекта
bf.Serialize(fs, exp);
//Запоминаем позицию, куда будет записан следующий элемент
nextExp = System.Convert.ToInt32(fs.Position);
//Перемещаем указатель на pos
fs.Seek(pos, SeekOrigin.Begin);
binWriter.Write(nextExp);
binWriter.Close();
binReader.Close();
fs.Close();
return;
}
fs.Seek(0, SeekOrigin.Begin);
nextExp = binReader.ReadInt64();
//Устанавливает текущее положение на 0 элемент
fs.Seek(nextExp, SeekOrigin.Begin);
//Запоминаем позицию
currentIndexNextExp = nextExp;
if (number < amount)
for (value = 0; value < amount; value++)//&& p != fs.Length
{
//Считываем указатель на 1 элемент
nextExp = binReader.ReadInt64();
//Если номер элемента соответсвует number, то произвести замену элемента на exp
if (value == number)
{
//Устанавливает текущее положение на nextExp предыдущего объекта
fs.Seek(previousIndexNextExp, SeekOrigin.Begin);
//Записываем указатель на конец файла
binWriter.Write(fs.Length);
//Устанавливает текущее положение в конец
fs.Seek(0, SeekOrigin.End);
//Запоминаем текущую позицию
long tempEnd = System.Convert.ToInt64(fs.Position);
//Записываем указатель на следующий элемент
binWriter.Write(nextExp);
//Запись объекта
bf.Serialize(fs, exp);
//Устанавливает текущее положение на nextExp следующего объекта
fs.Seek(nextExp, SeekOrigin.Begin);
//Производим поиск последнего элемента
previousIndexNextExp = nextExp;
while (nextExp != tempEnd)
{
previousIndexNextExp = nextExp;
nextExp = binReader.ReadInt64();
fs.Seek(nextExp, SeekOrigin.Begin);
}
//Меняем указатель последнего элемента на fs.Length
fs.Seek(previousIndexNextExp, SeekOrigin.Begin);
binWriter.Write(fs.Length);
binWriter.Close();
binReader.Close();
fs.Close();
//Прекрощаем выполнение метода
return;
}
//Устанавливает текущее положение на nextExp
fs.Seek(nextExp, SeekOrigin.Begin);
//p = System.Convert.ToInt64(fs.Position);
previousIndexNextExp = currentIndexNextExp;
currentIndexNextExp = nextExp;
}
//Устанавливает текущее положение в конец
fs.Seek(0, SeekOrigin.End);
//Запоминаем позицию для записи nextExp
long indexNextExp = System.Convert.ToInt32(fs.Position);
//Занимаем место под nextExp
binWriter.Write(nextExp);
//Запись объекта
bf.Serialize(fs, exp);
//Запоминаем позицию, куда будет записан следующий элемент
nextExp = System.Convert.ToInt32(fs.Position);
//Устанавливает текущее положение на nextExp
fs.Seek(indexNextExp, SeekOrigin.Begin);
binWriter.Write(nextExp);
binWriter.Close();
binReader.Close();
fs.Close();
amount++;
}
//Метод добавления после объекта
public void AddAfter(T exp, long number)
{
//Если количество объектов в файле равно нулю, завершить выполнение метода
if (amount == 0)
return;
//Если номер меньше нуля, завершить выполнение метода
if (number < 0)
return;
//Если номер больше либо равен количеству объектов в файле вызвать метод Add(exp, amount);
if (number >= amount - 1)
{
Add(exp, amount);
return;
}
//Указатель на следующий элемент
long nextExp = 0;
//Порядковый номер элемента
long value = 0;
//Индекс на nextExp предыдущего объекта
long previousIndexNextExp = 0;
//Индекс на nextExp текущего объекта
long currentIndexNextExp = 0;
BinaryFormatter bf = new BinaryFormatter();
FileStream fs;
fs = new FileStream(fileName, FileMode.Open);//открываем файл
BinaryWriter binWriter = new BinaryWriter(fs);
BinaryReader binReader = new BinaryReader(fs);
//Устанавливает текущее положение на начало файла fs.Seek(0, SeekOrigin.Begin);
//Указатель на нулевой элемент
nextExp = binReader.ReadInt64();
//Если в файле нет ни одного объекта, то останавливаем выполнение функции
//Устанавливает текущее положение на нулевой элемент
fs.Seek(nextExp, SeekOrigin.Begin);
//Запоминаем значение nextExp
currentIndexNextExp = nextExp;
while (true)
{
//Считываем указатель на следующий элемент
nextExp = binReader.ReadInt64();
//Если value равен number+1 осуществить вставку элемента
if (number == value - 1)
{
//Устанавливает текущее положение на nextExp предыдущего объекта (value -1)
fs.Seek(previousIndexNextExp, SeekOrigin.Begin);
//Запоминаем указатель на следующий элемент (value)
long temp = binReader.ReadInt64();
//Устанавливает текущее положение на nextExp предыдущего объекта (value -1)
fs.Seek(previousIndexNextExp, SeekOrigin.Begin);
//Записываем указатель на конец файла
binWriter.Write(fs.Length);
//nextExp присваиваем значение указателя на следующий элемент
nextExp = temp;
//Устанавливает текущее положение в конец файла
fs.Seek(0, SeekOrigin.End);
//Запоминаем позицию
long tempEnd = System.Convert.ToInt64(fs.Position);//Получаем //Записываем указатель на элемент value
binWriter.Write(nextExp);
//Запись объекта
bf.Serialize(fs, exp);
//Поиск последнего элемента и изменение его указателя
fs.Seek(nextExp, SeekOrigin.Begin);
temp = binReader.ReadInt64();
if (temp == tempEnd)
{
fs.Seek(nextExp, SeekOrigin.Begin);
binWriter.Write(fs.Length);
}
else
{
previousIndexNextExp = nextExp;
fs.Seek(nextExp, SeekOrigin.Begin);
while (nextExp != tempEnd)
{
previousIndexNextExp = nextExp;
nextExp = binReader.ReadInt64();
fs.Seek(nextExp, SeekOrigin.Begin);
}
fs.Seek(previousIndexNextExp, SeekOrigin.Begin);
binWriter.Write(fs.Length);
}
binWriter.Close();
binReader.Close();
amount++;
fs.Close();
return;
}
fs.Seek(nextExp, SeekOrigin.Begin);//Перемещаем указатель на nextExp
previousIndexNextExp = currentIndexNextExp;
currentIndexNextExp = nextExp;
value++;
}
}
//Метод чтения объекта по номеру
public T Read(long number)
{
if (number < 0 || number >= amount)
return default(T);
T exp = default(T);
long pos = 0;
long nextExp = 0;
long previousIndexNextExp = 0;
long value = 0;
BinaryFormatter bf = new BinaryFormatter();
FileStream fs = new FileStream(fileName, FileMode.Open);//открываем файл
BinaryReader binReader = new BinaryReader(fs);
//Устанавливаем текущее положение на начало файла
fs.Seek(0, SeekOrigin.Begin);
//Считываем указатель на нулевой элемент
nextExp = binReader.ReadInt64();
// Устанавливаем текущее положение на нулевой элемент
fs.Seek(nextExp, SeekOrigin.Begin);
while (pos != fs.Length)
{
//Запоминаем указатель на текущий элемент
previousIndexNextExp = nextExp;
//Считываем указатель на следуюзий элемент
nextExp = binReader.ReadInt64();
//Если номер элемента соответствует number, то считать элемент и вернуть его
if (number == value)
{
exp = (T)bf.Deserialize(fs);
binReader.Close();
fs.Close();
return exp;
}
//Устанавливает текущее положение на следующий элемент
fs.Seek(nextExp, SeekOrigin.Begin);//Перемещаем указатель на nextExp
//Считываем текущее положение
pos = System.Convert.ToInt64(fs.Position);
value++;
}
binReader.Close();
fs.Close();
return default(T);
}
//Метод чтения объекта по номеру
public void Read(ref T exp, long number)
{
if (number < 0)
return;
if (number < amount)
{
long nextExp = 0;
long previousIndexNextExp = 0;
long value = 0;
bool flag = false;
BinaryFormatter bf = new BinaryFormatter();
FileStream fs = new FileStream(fileName, FileMode.Open);//открываем файл
BinaryReader binReader = new BinaryReader(fs);
long p = 0;
fs.Seek(0, SeekOrigin.Begin);
nextExp = binReader.ReadInt64();
fs.Seek(nextExp, SeekOrigin.Begin);
long pp = System.Convert.ToInt64(fs.Position);
while (p != fs.Length)
{
previousIndexNextExp = nextExp;
//value = binReader.ReadInt64();
nextExp = binReader.ReadInt64();
if (number == value)
{
flag = true;
exp = (T)bf.Deserialize(fs);
binReader.Close();
fs.Close();
return;
}
fs.Seek(nextExp, SeekOrigin.Begin);//Перемещаем указатель на nextExp
p = System.Convert.ToInt64(fs.Position);
value++;
}
p = fs.Length;
if (number == value)
{
flag = true;
fs.Seek(nextExp, SeekOrigin.Begin);//Перемещаем указатель на nextExp
nextExp = binReader.ReadInt64();
}
if (flag) exp = (T)bf.Deserialize(fs);
binReader.Close();
fs.Close();
}
}
//Сортировка по возрастанию
public void Sorting()
{
BinaryFormatter bf = new BinaryFormatter();
FileStream fs = new FileStream(fileName, FileMode.Open);
BinaryWriter binWriter = new BinaryWriter(fs);
BinaryReader binReader = new BinaryReader(fs);
T min = default(T);
T temp = default(T);
//Объект exp будет использоваться, для того чтобы поменять местами объекты min и temp
T exp = default(T);
//Для объекта min
//Положение указателя прошлого элемента
long indexPreviousMinNextExp = 0;
//Положение указателя текущего элемента
long indexMinNextExp = 0;
//Указатель на следующий элемент
long minNextExp = 0;
//Для объекта temp
///Положение указателя прошлого элемента
long indexPreviousTempNextExp = 0;
//Положение указателя текущего элемента
long indexTempNextExp = 0;
//Указатель на следующий элемент
long tempNextExp = 0;
//Устанавливает текущее положение на начало
fs.Seek(0, SeekOrigin.Begin);
//Считываем указатель на нулевой элемент
minNextExp = binReader.ReadInt64();
//Для сортировки используем метод пузырька
for (int i = 1; i < amount; i++)
{
//Запоминаем указатель на текущий элемент
indexMinNextExp = minNextExp;
//Устанавливает текущее положение на слелующий элемент
fs.Seek(minNextExp, SeekOrigin.Begin);
//Считываем указатель на следующий элемент
minNextExp = binReader.ReadInt64();
//Десериализуем объект
min = (T)bf.Deserialize(fs);
indexPreviousTempNextExp = indexMinNextExp;
indexTempNextExp = minNextExp;
for (int j = i; j < amount && indexTempNextExp != fs.Length; j++)
{
//Перемещаем указатель на nextExp fs.Seek(indexTempNextExp, SeekOrigin.Begin);
//Считываем указатель на следующий элемент
tempNextExp = binReader.ReadInt64();
//Считываем объект
temp = (T)bf.Deserialize(fs);
//Сравниваем min и exp
// Операторы >,< не получаетя использовать, т.к. компиллятор выдает ошибку "Ошибка1Оператор ">" не может применяться к операндам типа "T" и "T""
//Придется использовать метод CompareTo интерфейса IComparable
//if (exp > min) {}
/*Меньше нуля - Значение этого объекта меньше значения параметра other.
Нуль - Значение этого объекта равно значению параметра other.
Больше нуля - Значение этого объекта больше значения параметра other*/
if (min.CompareTo(temp) > 0)
{
//Меняем местами объекты min и exp
//Изменить предыдущей min указатель на указатель на temp
fs.Seek(indexPreviousMinNextExp, SeekOrigin.Begin);
binWriter.Write(indexTempNextExp);
//Изменить указатель temp на указатель minNextExp
if (indexTempNextExp == minNextExp)
{
minNextExp = indexPreviousTempNextExp;
}
fs.Seek(indexTempNextExp, SeekOrigin.Begin);
binWriter.Write(minNextExp);
//Изменить предыдущей temp указатель на указатель на min
fs.Seek(indexPreviousTempNextExp, SeekOrigin.Begin);
binWriter.Write(indexMinNextExp);
//Изменить указатель min на указатель tempNextExp
fs.Seek(indexMinNextExp, SeekOrigin.Begin);
binWriter.Write(tempNextExp);
long position = indexMinNextExp;
indexMinNextExp = indexTempNextExp;
indexPreviousTempNextExp = position;
indexTempNextExp = tempNextExp;
// indexPreviousMinNextExp = exp = min;
min = temp;
temp = exp;
continue;
}
indexPreviousTempNextExp = indexTempNextExp;
indexTempNextExp = tempNextExp;
}
indexPreviousMinNextExp = indexMinNextExp;
}
binReader.Close();
binWriter.Close();
fs.Close();
}
//Метод удаление объекта
public void DeleteNode(long number)
{
//Проверка
if (number < 0 || number >= amount)
return;
// long pos = 0;
long nextExp = 0;
//Порядковый номер элемента
long value = 0;
//Положение указателя предыдущего элемента
long previousIndexNextExp = 0;
//Положение указателя текущего элемента
long currentIndexNextExp = 0;
BinaryFormatter bf = new BinaryFormatter();
FileStream fs;
fs = new FileStream(fileName, FileMode.Open);//открываем файл
BinaryWriter binWriter = new BinaryWriter(fs);
BinaryReader binReader = new BinaryReader(fs);
//Устанавливаем текущее положение на начало
fs.Seek(0, SeekOrigin.Begin);
//Считываем указатель на нулевой элемент
nextExp = binReader.ReadInt64();
//Запоминаем указатель на нулевой элемент
currentIndexNextExp = nextExp;
//Устанавливаем текущее положение на элемент первый элемент
fs.Seek(nextExp, SeekOrigin.Begin);
for (long i = 0; i < amount; i++)//&& pos != fs.Length
{
//Считываем указатель на следующий элемент
nextExp = binReader.ReadInt64();
//Если номер элемента соответствует number, то изменить указатель предыдущего элемента
if (value == number)
{
//Устанавливаем текущее положение на указатель предыдущего элемента
fs.Seek(previousIndexNextExp, SeekOrigin.Begin);
//Записываем указатель на следующий элемент
binWriter.Write(nextExp);
amount--;
binWriter.Close();
binReader.Close();
fs.Close();
return;
}
//Устанавливаем текущее положение на указатель следующего элемента
fs.Seek(nextExp, SeekOrigin.Begin);
// pos = System.Convert.ToInt64(fs.Position);
previousIndexNextExp = currentIndexNextExp;
currentIndexNextExp = nextExp;
value++;
}
binWriter.Close();
binReader.Close();
fs.Close();
}
//Обновление
public void Update()
{
BinaryFormatter bf = new BinaryFormatter();
FileStream fs = new FileStream(fileName, FileMode.Open);
FileStream temp = new FileStream("temp.bin", FileMode.Create);
BinaryWriter binWriter = new BinaryWriter(temp);
BinaryReader binReader = new BinaryReader(fs);
// long pos = 0;
long nextExp = 0; long indexNextExp = 0;
T exp;
//Устанавливаем текущее положение на начало
fs.Seek(0, SeekOrigin.Begin);
temp.Seek(0, SeekOrigin.Begin);
//Считываем указатель на нулевой элемент
nextExp = binReader.ReadInt64();
//Проверка
if (nextExp == 0)
{
//Если указатель на нулевой элемент равено 0, то записать в файл temp указатель равный 0
//Переименовать temp в fileName, и затем удалить fileName
binWriter.Write((long)0);
binWriter.Close();
binReader.Close();
fs.Close();
File.Delete(fileName);//Удаляем файл fileName
//Переименовываем temp.bin в fileName
FileInfo fi = new FileInfo("temp.bin");
fi.MoveTo(fileName);
return;
}
//Устанавливаем текущее положение на нулевой элемент
fs.Seek(nextExp, SeekOrigin.Begin);
//Записываем в файл temp указатель на нулевой элемень
binWriter.Write((long)sizeof(long));
for (long i = 0; i < amount; i++)//&& pos != fs.Length
{
//Считываем указатель на следующий элемент
nextExp = binReader.ReadInt64();
//Десериализуем объект
exp = (T)bf.Deserialize(fs);
//Устанавливаем текущее положение на следующий элемент
fs.Seek(nextExp, SeekOrigin.Begin);
//Запоминаем текущее положение в файле temp
indexNextExp = System.Convert.ToInt64(temp.Position);
//Занимаем место под nextExp
binWriter.Write(nextExp);
//Сериализуем объект
bf.Serialize(temp, exp);
//Запоминаем позицию, куда будет записан следующий элемент
nextExp = System.Convert.ToInt32(temp.Position);
//Устанавливаем текущее положение indexNextExp
temp.Seek(indexNextExp, SeekOrigin.Begin);
//Записываем указатель на следующий элемент
binWriter.Write(nextExp);
//Устанавливаем текущее положение в файле temp на конец
temp.Seek(0, SeekOrigin.End);
//pos = System.Convert.ToInt64(fs.Position);
}
binWriter.Close();
binReader.Close();
fs.Close();
//Удаляем файл fileName
File.Delete(fileName);
//Переименовываем temp.bin в fileName
FileInfo fI = new FileInfo("temp.bin");
fI.MoveTo(fileName);
}
//Метод удаления файла
public void delete()
{
//Закрыть файл
this.Close();
//Удалить файл
File.Delete(fileName);
}
}
}
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
/*Для подключения возможностей по работе с файлами необходимо добавить пространство имён System.IO в программу.*/
using System.IO;
using System.Diagnostics;
namespace course_work
{
class Program
{
static void Main(string[] args)
{
string name = "";
ConsoleKeyInfo cki;
Console.WriteLine("Используется мод FileMode.OpenOrCreate.");
Console.WriteLine("Если файл не сушествует, то он будет создан.");
do
{
Console.Write("Введите полное имя файла:");
name = Console.ReadLine();
Console.WriteLine("Если объект типа string, то нажмите S");
Console.WriteLine("Если объект типа date, то нажмите D");
Console.WriteLine("Для выхода из программы выбора нажмите Escape");
cki = Console.ReadKey(true);
if (cki.Key == ConsoleKey.S)
{
Console.WriteLine("Объект типа string");
newFile<string> e = new newFile<string>(name, FileMode.OpenOrCreate);
Console.WriteLine("Количество элементов в файле {0}", e.Amount);
Console.WriteLine("Для выхода в меню выбора нажмите M, для выхода из программы Escape");
Console.WriteLine("--------------------------------------");
Console.WriteLine("| Добавление в начало файла |0|");
Console.WriteLine("--------------------------------------");
Console.WriteLine("| Добавление в конец файла |1|");
Console.WriteLine("--------------------------------------");
Console.WriteLine("| Замена элемента |2|");
Console.WriteLine("--------------------------------------");
Console.WriteLine("| Добавление после элемента |3|");
Console.WriteLine("--------------------------------------");
Console.WriteLine("| Для чтения из файла нажмите |4|");
Console.WriteLine("--------------------------------------");
Console.WriteLine("| Для удаления элемента нажмите |5|");
Console.WriteLine("--------------------------------------");
Console.WriteLine("| Для сортировки нажмите |6|");
Console.WriteLine("--------------------------------------");
Console.WriteLine("| Для обновления файла нажмите |7|");
Console.WriteLine("--------------------------------------");
Console.WriteLine("| Для удаления файла нажмите |8|");
Console.WriteLine("--------------------------------------");
do
{
cki = Console.ReadKey(true);
if (cki.Key == ConsoleKey.M)
{
break;
}
if (cki.Key == ConsoleKey.D0)
{
Console.WriteLine("===Добавление в начало файла===");
Console.Write("Введите количество элементов:");
long n = Convert.ToInt64(Console.ReadLine());
for (long i = 0; i < n; i++)
{
Console.Write("Элемент {0}:", i);
e[i] = Console.ReadLine();
}
Console.WriteLine("Ввод элементов завершен");
}
if (cki.Key == ConsoleKey.D1)
{
Console.WriteLine("===Добавление в конец файла===");
Console.Write("Введите количество элементов:");
long n = Convert.ToInt64(Console.ReadLine());
for (long i = 0; i < n; i++)
{
Console.Write("Элемент {0}:", e.Amount);
e[e.Amount] = Console.ReadLine();
}
Console.WriteLine("Ввод элементов завершен");
}
if (cki.Key == ConsoleKey.D2)
{
Console.WriteLine("===Замена элемента===");
Console.Write("Введите индекс элемента:");
long n = Convert.ToInt64(Console.ReadLine());
Console.Write("Элемент {0}:", n);
e[n] = Console.ReadLine();
Console.WriteLine("Замена элемента завершена");
}
if (cki.Key == ConsoleKey.D3)
{
Console.WriteLine("===Добавление после элемента===");
Console.Write("Введите номер элемента, после которого необходимо вставить элемент:");
long n = Convert.ToInt64(Console.ReadLine());
Console.Write("Элемент {0}:", n);
e.AddAfter(Console.ReadLine(), n);
Console.WriteLine("Выполнение метода завершено");
}
if (cki.Key == ConsoleKey.D4)
{
Console.WriteLine("===Вывод элементов===");
for (long i = 0; i < e.Amount; i++)
{
Console.WriteLine("Элемент {0}:{1}", i, e[i]);
}
Console.WriteLine("Вывод элементов закончен");
}
if (cki.Key == ConsoleKey.D5)
{
Console.WriteLine("===Удаления элемента===");
Console.Write("Введите номер элемента:");
long n = Convert.ToInt64(Console.ReadLine());
e.DeleteNode(n);
Console.WriteLine("Выполнение метода завершено.", n);
}
if (cki.Key == ConsoleKey.D6)
{
Console.WriteLine("===Сортировка===");
e.Sorting();
Console.WriteLine("Сортировка завершена");
}
if (cki.Key == ConsoleKey.D7)
{
Console.WriteLine("===Обновление файла===");
e.Update();
Console.WriteLine("Обновление файла завершено");
}
if (cki.Key == ConsoleKey.D8)
{
Console.WriteLine("===Удаление файла===");
e.delete();
Console.WriteLine("Удаление файла завершено");
break;
}
} while (cki.Key != ConsoleKey.Escape);
}
if (cki.Key == ConsoleKey.D)
{
Console.WriteLine("Объект типа date");
newFile<date> e = new newFile<date>(name, FileMode.OpenOrCreate);
Console.WriteLine("Количество элементов в файле {0}", e.Amount);
Console.WriteLine("Для выхода в меню выбора нажмите M, для выхода из программы Escape");
Console.WriteLine("--------------------------------------");
Console.WriteLine("| Добавление в начало файла |0|");
Console.WriteLine("--------------------------------------");
Console.WriteLine("| Добавление в конец файла |1|");
Console.WriteLine("--------------------------------------");
Console.WriteLine("| Замена элемента |2|");
Console.WriteLine("--------------------------------------");
Console.WriteLine("| Добавление после элемента |3|");
Console.WriteLine("--------------------------------------");
Console.WriteLine("| Для чтения из файла нажмите |4|");
Console.WriteLine("--------------------------------------");
Console.WriteLine("| Для удаления элемента нажмите |5|");
Console.WriteLine("--------------------------------------");
Console.WriteLine("| Для сортировки нажмите |6|");
Console.WriteLine("--------------------------------------");
Console.WriteLine("| Для обновления файла нажмите |7|");
Console.WriteLine("--------------------------------------");
Console.WriteLine("| Для удаления файла нажмите |8|");
Console.WriteLine("--------------------------------------");
string partNumber = "00000000";
int price = 0;
int storageLife = 0;
do
{
cki = Console.ReadKey(true);
if (cki.Key == ConsoleKey.M)
{
break;
}
if (cki.Key == ConsoleKey.D0)
{
Console.WriteLine("===Добавление в начало файла===");
Console.Write("Введите количество элементов:");
long n = Convert.ToInt64(Console.ReadLine());
for (long i = 0; i < n; i++)
{
Console.WriteLine("Элемент {0}:", i);
Console.Write("\tНазвание:");
name = Console.ReadLine();
Console.Write("\tАртикуль:");
partNumber = Console.ReadLine();
Console.Write("\tЦена:");
price = System.Convert.ToInt32(Console.ReadLine());
Console.Write("\tСрок годности:");
storageLife = System.Convert.ToInt32(Console.ReadLine());
date exp = new date(name, partNumber, price, storageLife);
e[i] = exp;
}
Console.WriteLine("Ввод элементов завершен");
}
if (cki.Key == ConsoleKey.D1)
{
Console.WriteLine("===Добавление в конец файла===");
Console.Write("Введите количество элементов:");
long n = Convert.ToInt64(Console.ReadLine());
for (long i = 0; i < n; i++)
{
Console.WriteLine("Элемент {0}:", i);
Console.Write("\tНазвание:");
name = Console.ReadLine();
Console.Write("\tАртикуль:");
partNumber = Console.ReadLine();
Console.Write("\tЦена:");
price = System.Convert.ToInt32(Console.ReadLine());
Console.Write("\tСрок годности:");
storageLife = System.Convert.ToInt32(Console.ReadLine());
date exp = new date(name, partNumber, price, storageLife);
e.Add(exp);
}
Console.WriteLine("Ввод элементов завершен");
}
if (cki.Key == ConsoleKey.D2)
{
Console.WriteLine("===Замена элемента===");
Console.Write("Введите индекс элемента:");
long n = Convert.ToInt64(Console.ReadLine());
Console.WriteLine("Элемент {0}:", n);
Console.Write(" Название:");
name = Console.ReadLine();
Console.Write(" Артикуль:");
partNumber = Console.ReadLine();
Console.Write(" Цена:");
price = System.Convert.ToInt32(Console.ReadLine());
Console.Write(" Сток годности:");
storageLife = System.Convert.ToInt32(Console.ReadLine());
date exp = new date(name, partNumber, price, storageLife);
e[n] = exp;
Console.WriteLine("Замена элемента завершена");
}
if (cki.Key == ConsoleKey.D3)
{
Console.WriteLine("===Добавление после элемента===");
Console.Write("Введите номер элемента, после которого необходимо вставить элемент:");
long n = Convert.ToInt64(Console.ReadLine());
Console.WriteLine("Элемент {0}:", n);
Console.Write(" Название:");
name = Console.ReadLine();
Console.Write(" Артикуль:");
partNumber = Console.ReadLine();
Console.Write(" Цена:");
price = System.Convert.ToInt32(Console.ReadLine());
Console.Write(" Сток годности:");
storageLife = System.Convert.ToInt32(Console.ReadLine());
date exp = new date(name, partNumber, price, storageLife);
e.AddAfter(exp, n);
Console.WriteLine("Вставка элемента завершена");
}
if (cki.Key == ConsoleKey.D4)
{
Console.WriteLine("===Вывод элементов===");
for (long i = 0; i < e.Amount; i++)
{
Console.WriteLine("Элемент {0}:", i);
e[i].print();
}
Console.WriteLine("Вывод элементов закончен");
}
if (cki.Key == ConsoleKey.D5)
{
Console.WriteLine("===Удаления элемента===");
Console.Write("Введите номер элемента:");
long n = Convert.ToInt64(Console.ReadLine());
e.DeleteNode(n);
Console.WriteLine("Элемент {0} удален.", n);
}
if (cki.Key == ConsoleKey.D6)
{
Console.WriteLine("===Сортировка===");
e.Sorting();
Console.WriteLine("Сортировка завершена");
}
if (cki.Key == ConsoleKey.D7)
{
Console.WriteLine("===Обновление файла===");
e.Update();
Console.WriteLine("Обновление файла завершено");
}
if (cki.Key == ConsoleKey.D8)
{
Console.WriteLine("===Удаление файла===");
e.delete();
Console.WriteLine("Удаление файла завершено");
break;
}
} while (cki.Key != ConsoleKey.Escape);
}
} while (cki.Key != ConsoleKey.Escape);
Stopwatch stopWatch = new Stopwatch();
newFile<int> temp = new newFile<int>("temp.bin", FileMode.CreateNew);
stopWatch.Start();
for (int i = 1000; i > 0; i--)
{
temp.Add(i);
}
stopWatch.Stop();
// Get the elapsed time as a TimeSpan value.
TimeSpan ts = stopWatch.Elapsed;
// Format and display the TimeSpan value.
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10);
Console.WriteLine("Добавление 1000 элементов: " + elapsedTime);
stopWatch.Start();
Console.WriteLine(temp.Read(999));
stopWatch.Stop();
// Get the elapsed time as a TimeSpan value.
TimeSpan tts = stopWatch.Elapsed;
// Format and display the TimeSpan value.
elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
tts.Hours, tts.Minutes, tts.Seconds,
tts.Milliseconds / 10);
Console.WriteLine("Чтение 500 элемента: " + elapsedTime);
stopWatch.Start();
temp.Sorting();
stopWatch.Stop();
// Get the elapsed time as a TimeSpan value.
ts = stopWatch.Elapsed;
// Format and display the TimeSpan value.
elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10);
Console.WriteLine("Сортировка 1000 элементов: " + elapsedTime);
temp.delete();
}
}
date.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace course_work
{
[Serializable]
class date : IComparable<date>
{
protected string name = "";
protected string partNumber = "00000000";
protected int price = 0;
protected int storageLife = 0; //Срок хранения продуктов, в днях
public int CompareTo (date other)
{ return this.price.CompareTo(other.price);
}
public date() { }
UnicodeEncoding uniEncoding = new UnicodeEncoding();
public date(string name, string partNumber, int price, int storageLife)
{
this.name = name;
this.partNumber = partNumber;
this.price = price;
this.storageLife = storageLife;
}
public override string ToString()
{ return (System.String.Format("{0}{1}{2}",name, price, storageLife, partNumber));
}
public void print()
{
Console.WriteLine("\tНазвание: {0}; \n\tАртикул: {1}; \n\tЦена: {2}; \n\tсрок годности: {3}",name, partNumber, price, storageLife );
}
}
}
2
Документ
Категория
Рефераты
Просмотров
60
Размер файла
310 Кб
Теги
семестр, работа, программирование, курсовая
1/--страниц
Пожаловаться на содержимое документа