Типизированные файлы в С#

  • Автор темы Visor_ck
  • Дата начала
Статус
Закрыто для дальнейших ответов.
V

Visor_ck

#1
Всем доброго времени суток.

У меня такой вопрос: как в C# работать с типизированными файлами ?

Например:

у меня есть струтура

public struct sAddress
{
public string City;
public string District;
public string Street;
public string ZipCode;
public string Phone;
}

как мне организовать запись а файл объектов такого типа ?

P.S.
Прошу сильно не пинать.
 
P

Pasha

#2
Полного аналога типизированных файлов в .net нет. Сохрнять/загружать объекты можно при поможи сериализации, примерно так:
Код:
namespace Sample
{
[Serializable()]
public struct Address
{
public string City;
public string District;
public string Street;
public string ZipCode;
public string Phone;
}

class Program
{
static void Main(string[] args)
{
string filename = "test.dat";
Address[] adressesToSave = new Address[5];

// заполняем данными
adressesToSave[0].City = "Minsk";
// ....
adressesToSave[1].City = "Brest";
// ....

BinaryFormatter formatter = new BinaryFormatter();

FileStream outputStream = File.OpenWrite(filename);
formatter.Serialize(outputStream, adressesToSave);
outputStream.Close();

FileStream inputStream = File.OpenRead(filename);
Address[] loadedAddresses = (Address[])formatter.Deserialize(inputStream);
inputStream.Close();
}
}
}
Если надо сохранять в более "читабельном" формате, без привязки к конкретному приложению - используй xml-сериализацию.
 
N

Netizen

#3
Вопрос по сериализации: как можно правильно сериализовать сложный класс, т.е. содержащий экземпляр другого класса, ведь при обычном методе компилятор матерится. Если из него убрать эти экземпляры и оставить только переменные стандартных типов (string, boolean, integer и т.д.), то все работает нормально. Заранее благодарен. :)
 
S

Sunrise

#4
Для: Netizen
Код:
[Serializable]
class Foo
{
int a;
int b;
int c;
}

[Serializable]
class Bar
{
Foo foo;
int d;
}

class Program
{
static void Main(string[] args)
{
Bar bar = new Bar();
FileStream stream = File.OpenWrite("1.dat");
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, bar);
}
}
Все работает... Может, у тебя не все классы имеют атрибут Serializable?
 
N

Netizen

#5
Для: Sunrise
Скорее всего в этом и ошибка. Я не писал перед классами [Serializable]. Спасибо большое за помощь. :)
 
V

Visor_ck

#6
Большое спасибо :).

Еще такой вопрос:
если я таким образом записал в файл, на пример, 15 записей, как мне обратиться к записи на прямую, зная индекс. (не пребирая все предидущие)

Заранее благодарен :)
 
N

NikSoft

#7
Для: Visor_ck
Пиши записи, например, в ArrayList, который сохраняй в файл.
Считывай содержимое файла в ArrayList и обращайся к записи по известному тебе индексу.
 
V

Visor_ck

#8
Для: Visor_ck
Пиши записи, например, в ArrayList, который сохраняй в файл.
Считывай содержимое файла в ArrayList и обращайся к записи по известному тебе индексу.
Это не совсем то, что мне нужно :). при такой работе, если у меня будет довольно большой файл с зарисями (хотя бы метров 200), грузить в ArrayList оно будет очень долго.
Я имел ввиду считывание из файла только одной записи, по известному индексу.
Такое в Делфи примерно так делалось: seek(f, sizeof(мой_тип) * n) где f - файл n - номер записи.
Ипользование БД для хранения не предлогать :). Задание стоит сделать все именно через файлы.
 
S

Sunrise

#9
Для: Visor_ck
Что, если не сериализовать, а сохранять в xml? То есть делать записи типа
Код:
<Address>
<Number>1</Number>
<City>Minsk</City>
...
<Phone>111111</Phone>
</Address>
А потом доставать из файла запись с нужным тебе значением Number.
 
V

Visor_ck

#10
Насчет XML думал, в принципе, вариант, но хочется все же с файлами разобраться.
 
P

Pasha

#11
Для: Sunrise
Это не решает проблему загрузки всего файла в память перед его использованием. Да и сохранение в XML - это та же самая сериализация, только в другой формат.
Для: Visor_ck
В C# точного аналога sizeof для объекта нет, хотя бы потому, что ты не ограничиваешь длину string. И поэтому узнать смещение определенной записи в файле в приципе невозможно без перебора всех записей до нее.
Есть вот примерно такие варианты:
1. Сериализовать каждую запись отдельно в MemoryStream, в отдельный файл сохранять смещения всех записей - что-то вроде оглавления.
2. Если сам формат файла не важен, попробуй использовать SQL Server 2005 Compact Edition. Это набор библиотек, позволяющий работать с файлом базы данных в формате sdf.
 
Статус
Закрыто для дальнейших ответов.