Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Жизнь в отсутствии указателей C# 
:(
    Опции темы
EqKeeper
Дата 18.2.2010, 07:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 13.2.2010

Репутация: нет
Всего: нет



Доброго времени суток!
Всю жизнь сидел на C++Builder, но благодаря обитателям этого (и не только) форума, решил освоить что-нибудь еще. И поставил себе Visual Studio 2008 и создал проект на C# (прошу прощения, но раздела по нему не нашел, потому пишу сюда).

И сразу мне этот язык понравился, но вопросов возникла масса. Раньше я терпеть не мог указатели. И только сейчас, когда их лишился, понял - какая это замечательная штука!
Возникло масса вопросов, касательно порта CB-проекта на новую основу. В частности:

1) Есть структура с разнообразным содержимым, в том числе вложенными структурами и битовыми полями - как считать ее (или в нее - как правильно?) из файла? В C++ это делалось элементарно, но здесь указатель не передашь, да и функции наверняка уже нет... Так что вопрос - как или лучше даже чем ее считать? Очень желательно с коротеньким примером.

2) Есть древо каталогов на основе TreeView (первый раз его сам писал, так что, может, не в ту сторону копал...). Ноды можно помечать флажками. Задача - сделать поиск файлов только внутри помеченных флажками каталогов и вывести список файлов. Если бы шли они по порядку, да с самого верха (от диска), то проблем бы не было. А так сам диск может быть и не помечен - вначале нужно сформировать массив помеченных нодов. И вот тут очередной ступор - как? Написал функцию, но, видимо, не верно:

Код
public void FindFiles(TreeView DirList, ListView FilesList, string Extension)
        {
            TreeNode[] CheckedNodes = new TreeNode[0];
            foreach (TreeNode node in DirList.Nodes)
            {
                FindCheckedNodes(node, CheckedNodes);
            }
            foreach (TreeNode node in CheckedNodes)
            {
               ........................................................
            }
        }

        public void FindCheckedNodes(TreeNode Node, TreeNode[] NodeArray)
        {
            foreach (TreeNode n in Node.Nodes)
            {
                if (n.Checked)
                {
                    TreeNode[] tmp = new TreeNode[NodeArray.Length + 1];
                    Array.Copy(NodeArray, 0, tmp, 0, NodeArray.Length);
                    NodeArray = tmp;
                    NodeArray[NodeArray.Length - 1] = n;
                }
                FindCheckedNodes(n, NodeArray);
            }
        }


Возможно есть более простой способ или... или вообще - способ. ^^

Буду рад любой помощи!
PM MAIL   Вверх
Heinzz
Дата 18.2.2010, 19:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 381
Регистрация: 12.12.2008
Где: .net

Репутация: 3
Всего: 9



Цитата(EqKeeper @  18.2.2010,  07:36 Найти цитируемый пост)
1) Есть структура с разнообразным содержимым, в том числе вложенными структурами и битовыми полями - как считать ее (или в нее - как правильно?) из файла? В C++ это делалось элементарно, но здесь указатель не передашь, да и функции наверняка уже нет... Так что вопрос - как или лучше даже чем ее считать? Очень желательно с коротеньким примером.

если вновь создаваемая, то я бы сериализовал просто


--------------------
user posted image
PM MAIL   Вверх
EqKeeper
Дата 18.2.2010, 22:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 13.2.2010

Репутация: нет
Всего: нет



Вопрос с TreeView снимается. Я забыл о возможности создать "глобальный" массив и использовтаь его без всяких указателей. Ко всему прочему алгоритм работы был несколько изменен, наследуемое выделение убрано, а пометки сохраняются в-, и удаляются из- массива сразу после тыка по флажку.

Heinzz
Вот то жуткое слово я уже встречал. Что это такое и как этим пользоваться? Как уже говорил - с примером, если не сложно. И еще немного не понял, что имелось ввиду под "вновь создаваемая". Есть структура.
struct SomeStruct
{
int a;
char b[32];
char c:1;
char d:2;
char e:1;
};
Есть файл, вначале которого идут 37 байт, которые нужно считать, соответственно раскидав по структуре. Первые 4 - в int a, следующие 32 - в char [] b, а последний разбить побитно.
PM MAIL   Вверх
EqKeeper
Дата 19.2.2010, 18:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 13.2.2010

Репутация: нет
Всего: нет



Неужели никто не знает? Чтобы было нагляднее, приведу кусок из программы на BCB - его-то и надо портировать на C#
Код
// Создаем структуру (57 байт)
typedef struct
{
  int a;
  int b;
  int c;
  char d[12];
  char e[32];
  char f:1;  // Это...
  char g:2; // ...биты
} FileHeader;

FILE *f; // файл
FileHeader head; //структура

//Открываем файл на двоичное чтение
f = fopen( "d:\some_file.dat", "rb");
//Читаем первые 57 байт файла f в структуру head
fread(&head, sizeof(FileHeader), 1, f);
//Закрываем файл
fclose(f);


... или, как вариант - расширение для C#, позволяющее это делать. Например - оформить это вот в качестве функции в C++, отправить в библиотеку и подключить к C#... Или еще что-нибудь... Если есть идеи - поделитесь пожалуйста! Только с примерами - я еще только учусь, а в мелкомягкой справке сам черт ногу сломит... да и термины там жуткие... >_>
PM MAIL   Вверх
KuMa1104
Дата 19.2.2010, 23:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 541
Регистрация: 16.4.2009
Где: Ростов-на-Дону

Репутация: 1
Всего: 3



Цитата(EqKeeper @  18.2.2010,  07:36 Найти цитируемый пост)
. И поставил себе Visual Studio 2008 и создал проект на C# .

И взял  земли и воды, и смешал их, и создал он тварей водяных и гадов с холодной кровью. И взял он воды и огня, и..   smile 

Почитайте про сериализацию рекомендую Троелсен Эндрю С# И платформа НЕТ!
Вот это от туда
 
Код

namespace CustomSerialization
{
    using System;
    using System.Runtime.Serialization;

    [Serializable]
    public class CustomCarType : ISerializable
    {
        public string petName;
        public int maxSpeed;

        public CustomCarType(string s, int i)
        { petName = s; maxSpeed = i;}

        // Impl of ISerializable interface
        public void GetObjectData(SerializationInfo si, StreamingContext ctx)
        {
            // What context is the stream?
            Console.WriteLine("[GetObjectData] Context State: " + ctx.State.ToString());

            // Fill the SerializationInfo type with out info.
            si.AddValue("CapPetName", petName);
            si.AddValue("maxSpeed", maxSpeed);
        }

        // You must supply a custom ctor with this signature
        // to allow the runtime engine to
        // set the state of your object.
        private CustomCarType(SerializationInfo si, StreamingContext ctx)
        {
            // What context is the stream?
            Console.WriteLine("[ctor] Context State: " + ctx.State.ToString());

            // Re-hydrate a new object based on incoming 
            // SerializationInfo type.
            petName = si.GetString("CapPetName");
            maxSpeed = si.GetInt32("maxSpeed");
        }
    }
}



Код

namespace CustomSerialization
{
    using System;
    using System.IO;
    using System.Runtime.Serialization.Formatters.Binary;
    public class Class1
    {

        public static int Main(string[] args)
        {
            // Make a car and listen to the tunes.
            Console.WriteLine("Making car...");
            CustomCarType myAuto = new CustomCarType("Siddhartha", 50);
            
            // Create a file stream.
            Console.WriteLine("Making *.dat file...");
            Stream myStream = File.Create("CarData.dat");
            
            // Move our graph into the stream using a binary format.
            Console.WriteLine("Saving to file.");
            BinaryFormatter myBinaryFormat = new BinaryFormatter();
            myBinaryFormat.Serialize(myStream, myAuto);
            myStream.Close();

            Console.WriteLine("Reading from file.");
            myStream = File.OpenRead("CarData.dat");

            CustomCarType carFromDisk = 
            (CustomCarType)myBinaryFormat.Deserialize(myStream);

            Console.WriteLine(carFromDisk.petName + " is alive!");
            myStream.Close();

            return 0;
        }
    }
}


Это сообщение отредактировал(а) KuMa1104 - 19.2.2010, 23:59


--------------------
Галактика – суровая штука. Чтобы в ней выжить, надо знать, где твое полотенце.

Время - штука относительная... а время обеда - ещё более относительная
PM MAIL   Вверх
EqKeeper
Дата 20.2.2010, 11:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 13.2.2010

Репутация: нет
Всего: нет



KuMa1104 
Спасибо, суть понял! Попробую написать у себя по аналогии с твоим примером. Если не получится... придется и впрямь читать книжку, хотя не люблю я это дело... один единственный раз мне понравилось читать док по C++, на каком-то сайте. Но там очень хорошо материал подавался. Что поделать - самоучка, мне легче по чужим скриптам учиться, чем по докам. =\
PM MAIL   Вверх
EqKeeper
Дата 20.2.2010, 13:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 13.2.2010

Репутация: нет
Всего: нет



Ехаем дальше. С се... сериализацией и де... десериализацией своих объектов я разобрался. Собрал структуру, сделал ее сериализируемой, изменил, сохранил в файл, потом считал - все прекрасно.
Но когда попытался таким образом считать файл, получил следующую ошибку:
Цитата
System.Runtime.Serialization.SerializationException: Недопустимый двоичный формат входного потока. Начало содержимого (в байтах):

Оно и понятно - если открыть файл блокнотиком, можно увидеть такую картину:
Цитата
    яяяя           @mp3test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null   mp3FReader.mp3Header   fild1fild2fild3fild4                      

Тобишь, сохраняя файл, он записывает туда кучу дополнительной информации для ее считывания. В готовом файле (в данном примере - mp3) понятное дело такой информации нет. Есть лишь последовательность байт, которую нужно прочитать и рассортировать по структуре. Смещение 0, длина 4 - это вот первое поле. Смещение 4 длина 16 - это второе и т.д.

Привожу код, надеюсь, что поможете разобраться - что я делаю неправильно... (записываю я класс или структуру - значения не имеет, видимо, потом что все они наследники object).

Код

namespace mp3Reader
{
    [Serializable]
    public struct mp3Header
    {
        public int fild1;
        public int fild2;
        public int fild3;
        public int fild4;
    }
}

...

using mp3Reader

...

 private bool mp3read(string FullPath)
        {
            using (FileStream fs = new FileStream(FullPath, FileMode.Open, FileAccess.Read))
            {
                BinaryFormatter formater = new BinaryFormatter();
                mp3Header mp3h = (mp3Header)formater.Deserialize(fs);
                Exit_button.Text = mp3h.fild2.ToString();
            }
            return true;
        }

PM MAIL   Вверх
KelTron
Дата 20.2.2010, 17:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 745
Регистрация: 8.10.2006
Где: Красноярск

Репутация: 11
Всего: 38





--------------------
Тысячами незримых нитей обвивает тебя Закон. Разрубишь одну - преступник. Десять - смертник. Все - Бог.
Эвенгар Салладорский, основатель Школы Тьмы.
PM MAIL   Вверх
EqKeeper
Дата 21.2.2010, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 13.2.2010

Репутация: нет
Всего: нет



Ммм... спасибо, посмотрю...
P.S. Уже объяснили, что сериализация в моем случае не подходит.
PM MAIL   Вверх
Heinzz
Дата 21.2.2010, 18:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 381
Регистрация: 12.12.2008
Где: .net

Репутация: 3
Всего: 9



напишите свой простой класс для чтения таких файлов. Вновь создаваемая - я имел в виду что если читать файлы уже сгенерированные не сериализацией то сериализация Вам не подходит, тк файлы имеют различный формат, в файле полученном путем сериализации есть информация о сохраненной структуре, а  в Вашей последосательности байтов нет.
открывайте поток и если знаете в какой последовательности записаны байты используйте ReadInt ReadChar ....


--------------------
user posted image
PM MAIL   Вверх
EqKeeper
  Дата 21.2.2010, 20:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 13.2.2010

Репутация: нет
Всего: нет



Heinzz
Да, с сериализацией я уже понял. А жаль. =\
Класс это конечно хорошо, но хочется универсализации. =\\ В BCB было все так просто и удобно... А здесь целый класс... =\\\

KelTron
Раскурочил ту демку. Большущее спасибо. Файл считал всеми тремя способами. Структуру заполнил - все прекрастно. Проблема одна - я не могу вытащить из файла строки. Предположим, у меня есть строка длиной 12 байт. В структуре я ее записываю как указано в той демке:

Код

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[] date;

Целочисленные данные до и после нее считываются на ура. Если же попробовать считать после прочтения some_struct.date.toString(), то для любого файла я получаю "System.Byte[]" или "System.Char[]", если пытаюсь считать как char'ы. Попытка выставить string вызывает ошибку TSize. Что делать? Что я делаю неправильно?
PM MAIL   Вверх
KelTron
Дата 22.2.2010, 13:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 745
Регистрация: 8.10.2006
Где: Красноярск

Репутация: 11
Всего: 38



Код

byte[] byteData = ...
string s = Encoding.ASCII.GetString(byteData);

Кодировку смотри сам, какая нужна.

Это сообщение отредактировал(а) KelTron - 22.2.2010, 13:09


--------------------
Тысячами незримых нитей обвивает тебя Закон. Разрубишь одну - преступник. Десять - смертник. Все - Бог.
Эвенгар Салладорский, основатель Школы Тьмы.
PM MAIL   Вверх
EqKeeper
Дата 22.2.2010, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 13.2.2010

Репутация: нет
Всего: нет



Большущее спасибо! Попробую.
PM MAIL   Вверх
EqKeeper
Дата 22.2.2010, 16:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 13.2.2010

Репутация: нет
Всего: нет



Все работает! Еще раз спасибо!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
Partizan
PashaPash

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, Partizan, PashaPash.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | .NET для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0972 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.