Pull to refresh

Comments 151

Я конечно не претендую на идеальное решение, но почему бы не модифицировать уже существующие классы под свои нужды?
Честно говоря не понял вашего вопроса. Если вы имеете ввиду классы сформированые утилитой xsd, то в статье указано, что при изменении структуры придется снова запускать утилиту xsd. В тоже время я изменил поведение класса FileStream под свои нужды путем наследования.
Я имел ввиду взять код XML десериализатора из .net и подправить в нём код под свои нужды. Просто то, что выложено в статье — это честно — катастрофический код.
Да, код не совсем хороший, у меня просто не было времени писать более удобовариемый. Но суть не в нем, а в самом методе. А то что вы предлагаете не годится, так как переписывать либы под свои нужды не совсем хорошо, мало ли где такая поделка может аукнутся, тем более в комерческом проекте. Да и виртуальные функции придумали специально для таких случаев.
Ну давайте по пунктам.
1) Эта задача уровня абстракции XML сериализатора, а не потока.
2) Если мы говорим о коммерческом проекте, то тот код, который представлен — в тысячу раз большее зло чем любые сложности с модификацией библиотечного класса.
3) Почему не хорошо переписывать либы под свои нужды, и в чем там могут быть проблемы?
4) Виртуальные функции упомянуты не к месту, т.к. см. пункт 1.
1) Я не хочу трогать сериализатор, я просто хочу чтобы он получал правильные данные, да и переделывать либу под каждый бздык разных задач слишком трудоемко.
2) Я не спорю, что это плохой код, в реальности будет другой, а библиотеку менять это еще большее зло, так как возникнет куча других проблем, например как потом быть с переделанной либой при установке приложения на другой комп.
3) А зачем это делать, если есть более лучше способ?
4) Почему не к месту? Если бы сериализатор предоставлял бы нужные мне, то я ими бы и воспользовался.
> 3) А зачем это делать, если есть более лучше способ?

Код из топика — это не «лучше способ», это катастрофа. Лучше бы взяли генератор синтаксических анализаторов — вот это было бы правильно если уж очень сильно нужно руками XML разбирать.
Я и не говорю, что код хороший, и вообще не думал его вылаживать. Вообще речь шла о методе, а реализация получилась не очень красивой, но сами подумайте можно ли сразу реализовать с ходу красивый код, иногда приходится переписывать, что я позже и сделаю
1) На уровне потоков вообще не существует XML, есть поток байт и источник, всё. Задача потока — подавать эти байты из источника. И упаси его знать про XML.
2) Чем зло? Взяли код библиотеки — поменяли неймспейс или имя класса и подцепили как обычный файл с кодом. И какие проблемы могут возникнуть при установке на другой комп?
3) Чем показанный способ лучше? Он нарушает абстракции, там есть костыли с буфером, да и переделать сериализатор — гораздо проще.
4) Потому что опять см. пункт 1. Переопределение потока — это переопределение потока. А у вас получается что вместо потока реализован свой костыль непонятно какого уровня абстракции. Вы подумайте, вы в одном и том же классе работаете и с XML и с битовым массивом, это категорически недопустимо.
1) Что плохого в том что я подменяю в потоке данные?
2) Зло в том, что в библиотеке еще нужно разобраться и найти места где нужно менять, плюс к этому нужно еще лишнии ненужные мегабайты потом тягать с собой и держать при этом сами правки. А тут всего лишь написал одну функцию и контролируешь весь процесс, и если надо, легко правишь нужные места. Вообще либы правятся в случае грубых ошибок в них, а не вслучае если вам не удобно, иначе так придется все платформу Net со своими правками тягать с собой.
3) Какую абстракцию я нарушил? Я воспользовался легальны способом и она работает на ура.
4)Опять двадцать пять, когда столкнетесь с моим случаем, вот перепишите все либы под себя, вот тогда и посмотрите что лучше.
Дальнейший спор бесполезен, я поступил как считаю нужным, и считаю что мой способ лучше и быстрее.
Мегабайты таскать не надо, всего 2-3 класса с мелкими правками. Если в библиотеке реализованно почти то что нужно, то почему бы не взять?

Зло в том — что вы путаете абстракции, на уровне потока не существует никакой структуры данных, это всё равно что в потоке картинку восстанавливать и разбирать по слоям. А в вашем случаее в этот уровень вносится структура XML, и более того — как-то заточенная под конкретный проект структура. Это очень и очень плохо.

Да и минус в том числе в том, что у вас «всего-то одна функция», когда тут работы на полноценный класс, а то и на несколько. Вы всё пихаете в одну функцию.

Вы воспользовались легальным способом исключительно с точки зрения синтаксиса языка, с точки зрения программирования — это грубейшая ошибка.

Я бы в этом случае тягал бы xml файлы через мок(практически)-типы, написать генератор для описанного в топике случая — 30-50 строк кода.

Считать можете как хотите, сообщество рейтингом оценивает вашу неправоту.
Причем тут абстракции? И что плохого в контроле за потоком? Многие программы так делают, и ничего страшного.
В вашем случае нужно еще заниматься изучением чужого кода, когда проще написать небольшое дополнение и забыть.

>Я бы в этом случае тягал бы xml файлы через мок(практически)-типы, написать генератор >для описанного в топике случая — 30-50 строк кода.
А если изменится структура, опять писать? В моем случае ничего вообще не нужно делать, в части чтения

Рейтинг плохой из-за нехорошего кода, сам способ тут не причем.
У меня такое ощущение что вы не совсем понимаете базовых вещей объектно-ориентированного программирования. Плохо то, что вы на уровне контроля за потоком реализуете высокоуровневую логику, это нарушает уровни абстракции.

Я же написал что это — генератор, так что ничего переписывать не надо.
Если бы я не понимал ООП, то не смог бы реализовать это. Я прекрасно понимаю, что делаю все на низком уровне, но так проще и универсальнее, тем более что не всегда есть возможности менять либы.
Приведенный выше код не является объектно-ориентированным — это первый факт. Второе — я уже несколько раз упомянул уровни абстракции, но вы, почему-то, пропускаете это мимо.

Я уже предложил вариант без замены либы — делать подобие mock-объектов, для описанного в топике случая — пойдет на ура.

Что значит проще и универсальнее? Кода у вас по объему много больше, понятность много меньше, поддерживаемость тоже, да и масштабируемость меньше, т.к. код завязан на конкретные фишки вашего xml'я. Я не вижу ни простоты, ни универсальности.
Честно говоря пока не представляю как можно это сделать через mock-объекты, и как бы в случае если нужно прочесть данные частями?

Я уже говорил, что код не очень, но сам метод помоему лучше чем предложенный вами, и при этом не нужно разбираться в чужом коде.

И как быть в вашем случае если исходный код библиотеки недоступен?
Давайте говорить аргументированно, чем описанный в топике метод лучше? Потенциально это несколько классов и пачка тестов (если писать как надо), я предлагаю более простой вариант.

Ну и мы же не говорим про библиотеки, исходный код которых недоступен, ведь мы же использовали только BCL.
Я уже говорил, что лучше тем что я контролирую поток данных, и на ходу правлю ошибки в нем, т. е. у меня полный контроль за данными. В вашем случае, такой контроль очень слабый, мало того нужно еще разбираться в каком месте нужно править да и еще носить кучу дублированного кода.

А я говорю еще про случаи когда исходный код недоступен, что бывает чаще всего.
Не понял про дублированный код, где он будет?
Если хотите править ошибки — правьте их на уровне выше, не надо мешать всё в кучу. Да и в вашем случае контроля никакого, код заточен под четкие «ошибки», в чем проявляются плюсы такого подхода?

К чему я всё это говорю? Просто люди читают хабр и часто воспринимают написанное здесь за чистую монету, и потом пишут похожий код, аргументируя это тем, что «а я на хабре видел» (ну и не обязательно только на хабре). Коли ресурс публичный, то и все ошибки говорим публично.
Напомню, что я предлагал вариант и без изменения библиотечного класса.
Если честно, то я больше специалист по С++, поэтому если не трудно объясните мне как можно реализовать через moсk-объекты
Делаете объект, который удовлетворяет требованиям сериализатора, и в который свободно десериализуются объекты, а внутри идет простая проверка и переброс значения в целевой объект, или преобразование, если необходимо.
Пока не понимаю вашей мысли. Какой объект, и как он должен работать?
Объект, который вы передаёте в сериализатор, сериализатор работает с ним (и работает успешно, т.к. этот объект «проглатывает» существующую структуру данных в xml), а при конструировании этого объекта уже определяются стандартные методы, или перебрасывающие значение в реальный объект, или вставляющие что-то стандартное или преобразующие данные. И никакой работы с xml, никакого сложного кода + универсальность, т.к. генератор будет одинакого хорошо работать с любой структурой, до тех пор, пока у вас не появятся совершенно новые «ошибки» в xml (нового типа), но в этом случае любой код придется переписывать без вариантов (т.к. тип «ошибок» заранее неизвестен).
Подождите, вы предлагаете вместо объекта сформированного утилитой xsd писать свой, который перекидывает данные куда надо, правильно? Но в таком случае он должен полностью копировать структуру созданного, а это несколько тысяч строк кода! Проще уже в сам конечный объект внести правки. И где тут универсальность?
Не надо ничего писать, пишется генератор проксей, который работает для любого объекта. В конце концов, я это раза три повторил!
Про генератор можно подробней?
Я всё написал выше, создаёте проксю, которая пропускает через себя все обращения к свойствам. Если вы не знаете что это такое — это говорит о вашем незнании ООП, елси не можете это реализовать — это говорит о вашем незнании .net в частности. В конце концов — если беретесь писать статью — разберитесь с базовыми приёмами, с платформой, с качеством написания кода… Я просто не могу и в данном случае не желаю всё разъяснять по строчкам кода что и как сделать.
А вы представляете насколько это будет медленно? И как в таком случае сдедать чтение частями? Не забывайте что у меня на обработке файлы по несколько гиг. Вы уж извените но ваш метод не только намного медленнее, но и на порядок сложнее, да и еще не учитывает тонкости которые описаны в статье. Да и еще забыл, онгда пользователь захочет остановить процесс досрочно, как быть в этом случае?
Это не будет медленно, у меня получается +1 доп. вызов функции, у вас же в текущей реализации если выделить методы — будет медленнее уже. Да и в любом случае даже 10 вызовов функции ничто по сравнению с ожиданием чтения с диска.
Частями — проблем нету, всё реализуется.

Остановить — пусть останавливает, максимум что он потеряет — это парсящийся в данный момент объект, ну это потеряется при любом останове, хотя опять же, можно и подождать пока допарсится текущий объект и остановить, проблем нет.

Чем метод сложнее? По объёму кодирования он меньше, по количеству логики — он вообще прозрачен.
Смотри в твоем случае нужна перехватывать все методы которые вызывают проблемы, что по сути довольно медленно, плюс к этому нужно их еще знать. Далее, если остановить поток, то когда? Где это можно определить? Да и как потом продолжить? Другими словами логика разбросана и в целом ее сложно уловить, да и не решает это моих проблем.
В моем случае все в одном месте (правда код не удачный, но это поправимо), да и анализировать проще чистый xml и быстрее, так как задержек никаких нет.
И прочем тут ожидание чтения? Ваш метод тоже зависит от этого.
Что значит перехватывать? Почему медленно? 1 доп. вызов функции, 1 проверка, это пообще копеечные операции на фоне всего остального.
А что останавливать? Мы все равно в нашем цикле будем сущности считывать одна за другой, в этом же цикле и тормознем, оттуда и продолжим.

Вот честно, вы или троллите так под вечер, или не представляете себе что такое .net в частности и как он работает.
Ладно, мы с вами на разных языках говорим, точнее о разных подходах, ваш метод не годится в моем случае, так как более трудоемкий и не решает проблем с остановками так как функция Deserialize() возвращает объект целиком готовый и как потом восстановить чтение в вашем случае не понятно. Лучше попробуйте реализовать то что но своим способом, вот тогда и поймете.
Я же выше это описал… Будьте объективны, и хотябы читайте несколько постов выше перед ответом. Или вам нужно код сразу подавать готовый, вместо советов как это надо сделать?
Я уже сказал, ваш способ не учитывает многие ньюансы которые тоже описал выше, но вы на них почему-то не обращаете внимания.
По моему спорить бесполезно, я говорю раз 5 что учитывает, вы отрицаете не приводя никаких аргументов. Чтож, удачи, надеюсь ваш проект провалится хотябы не так быстро, но с таким подходом это неизбежно.
Смешной ты, хотя тебе всего лишь 19 лет и опыта почти нет (я на 17 лет старше). Но ничего со временем поймешь. А проект, кстати, от такого решения только выиграл и будет еще долго рабовать своих пользователей ;)
Мы на ты ещё не переходили, не надо дерзить. Возраст тут мало что значит, как мы видим и в 35 можно писать вот такой быдлокод. Считаете что проект выиграл — считайте, до вашего проекта мне дела нет, ставлю цель только предупредить читателей топика о том, что описанными методами создавать решение строго нельзя. Не верите — спросите у более опытных коллег.
Ошибаетесь возраст многое значит, а насчет быдлокода, хотелось бы узнать сколько вы создали законченных приложений, которыми пользуются сотни пользователей? И вам скажу, пользователям наплевать на ваш код, им важен хороший интерфейс, который не всегда возможно обеспечить красивым кодом, я часто встречал проги у которых красивый код, как по книжке, в тоже время плохой интерфейс. Малоопытные прогеры этим часто страдают.
Чисто возраст не значит ничего, есть люди в 20-30 владеющие своими софт-фирмами, созданными ими с нуля на успешном продукте, или software-architect'ы, работающие в больших существующих фирмах, а есть те, кто в 50 — всё ещё на уровне Junior'а.

Видимо малоопытные прогеры страдают в том, что они делают и код, и интерфейс, и ещё кучу всего, хотя для каждой задачи свои люди. И разработчик отвечает за качество кода, дизайнер — за интерфейс.
И да, мне жаль тех разработчиков, которых заставляют делать интерфейс к разрабатываемому софту.
Чисто возраст не значит ничего, есть люди в 20-30…

без лишней скромности, я один из них. Но вы поймите меня правильно, мне тоже было 19 и тоже многое не понимал, что говорили более опытные коллеги, теперь я их понимаю, а молодые меня нет :)
С радостью, но это закрытые продукты, доступ к которым не всем позволен
Нет пруфа — нет разаботок. Сделать что-то малосложное для какой-нибудь организации может сейчас практически любой, открыть на этом фирму — +10000рублей и готово. Я имел ввиду что-то более серьёзное.
Вы знаетет что такое инжект? Вы значете как обходить фаерволы и антивирусы? Вы знаете как противодействоать таким атакам? Продолждать?
Пока вы говорите вещи которые даже больше академические чем технические, и могут показывать только объём, но не сложность проекта.

Да и коли речь зашла о защите сети — есть много классных продуктов больших фирм, вы владелец одной из них? Можно название фирмы (если это конечно не большая секретная информация для внутреннего пользования)).
Это все технические термины, а фирмы нет, все под заказ, а фирма это лишнее
Т.е. вы ещё и закон нарушаете, занимаясь предпринимательством без фирмы? Вы же выше сказали про «без лишней скоромности».
Или вас взяли на работу, и вы приравниваете это к владению фирмой?
Знаешь, я встречал таких упертых, по секрету скажу «Много шума, а делов нет»
Как это хорошо, лохануться с нарушением закона, написать говнокод, наврать про фирму и в итоге ещё перевести разговор на личности! Респект!
Ну вот и ладушки, бай-бай!
Подождите, вы предлагаете вместо объекта сформированного утилитой xsd писать свой, который перекидывает данные куда надо, правильно? Но в таком случае он должен полностью копировать структуру созданного, а это несколько тысяч строк кода! Проще уже в сам конечный объект внести правки. И где тут универсальность?
Занятно, уже не первый раз наблюдаю, как человек на слова «код плохой» отвечает «да, я знаю, у меня просто не было времени писать хороший». Тенденция.
Иногда нужен быстрый код, а он как правило не красивый ;)
Мне кажется, правильно было бы все-таки унаследовать от дотнетовского сериализатора, потом скопипастить оттуда то, что нуждается в правке и поправить под свои нужды.

Чтобы оно правильно легло в иерархию классов и им можно было бы безболезненно воспользоваться в методах, которые принимают параметром экземпляр дотнетовского сериализатора (if any).
По поводу найденного бага — если я правильно представляю работу с потоками (через StreamReader\Writer), то ваша проблема скорей всего в следующем — метод read не должен ничего возвращать по объему, меньше чем заданный буфер.
Т.е. Read должен накопить из потока в буфере некий объем данных и вернуть их.

Если возвращается 0 — это означает что поток просто кончился, т.е. прочитаны все данные ( и окончание данных «удачно» целиком поместилось в последний буфер

Если возвращается некое значение, но меньше чем буфер — это значит что «хвостик» данных или не целиком заполнил буфер или внутри потока что-то сломалось и ридер просто вернул содержимое, которое он успел «накопить».

Для меня поведение вполне логичное, как иначе можно возвращать остатки из потока если не в буфере? А уже внутренние механизмы видать определили, что если вернулся не полный буфер, а только часть, то дальше «ждать» наполнения буфера нет смысла и надо закрыть ридер.

Это поведение скорей всего зависит от индивидуальной реализации и в случае классов общего предназначения, типа StreamReader, регулируется каким-либо флагом или параметром конструктора…
Тогда почему не ведет себя подобным образом сериализатор? А он будет читать до тех пор пока я не возращу 0.

Такое поведение возможно оправдано для StreamReader\Writer в случае когда читаются файлы, но проблемы возникнут, если источником будет нечто другое, которое не может сразу возвращать указанное количество байт.
Есть подозрение, что вы не очень корректно заоверрайдили Read — поэтому поведение родного сериализатора и отличается от вашего десериализатора.

Ну так буфер для того и передается чтобы читать блоками из потока (неизвестной длины):
Если не было сигнала об окончании потока — «сиди и жди» до истечения таймаута — вдруг кто еще данные пришлет, с задержкой. А если метод возвращает буфер — значит или прочитал уже полный буфер или получил данные об изменении состояния — поток кончился или сломался.

Ну я не знаю как пояснить еще — представьте что у вас есть бесконечный бак с водой и с вентилем(это поток, объем воды неизвестен, но не бесконечен) и ведро на 10 литров — это ваш буфер.

И есть робот которого надо запрограммировать чтобы он ведром «перелил» всю воду из бака в речку. Как вы его запрограммируете на данную операцию? Тут важно чтобы он перелил всю воду, а не замер под вентилем с последним полупустым ведром…
Я все прекрасно знаю и понимаю, и считаю что такое поведение не верно, хотя реализовать такое проще, что и было сделано.
ну если вы считаете что МС в .NET впихивает только то, что проще реализовать — тогда действительно обсуждать особо нечего…
Поддержу, считаю описанное поведение read стандартным для классов, реализующих потоки и потоки-обертки, т.к. ввиду отсутствия внутренней структуры данных в потоке — мы всегда набиваем массив дополна. Хотя в этом плане могу где-то и заблуждаться.
В том то и дело что массив не всегда может быть заполнен до конца, но в случае с файлами такое поведение вполне нормально, но проблемы начнутся тогда когда вы будете читать не из файла. Хотя сами классы затачивались для чтения только из файлов.

Вот вам гепотетический случай, вы имеете либу которая читает данные из потока, этот поток формируете и заполняете вы, и для своего удобства не всегда полностью заполняете буфер. Предствьте как вы намучаетесь, если либа будет считать поток исчерпан только по тому, что не полностью заполнен буфер. Это вообще грубейшая ошибка. В моем случае десириализатор ведет себя правильно, когда простое чтение текстовых файлов не совсем верно.
Что значит «для вашего удобства не полностью заполняете буфер»? Где это может быть полезно? И когда без разрыва потока мы не можем заполнить буфер? Даже в случае организации туннеля через интернет, для потока поведение сохраняется.
Вы видать никогда не имели дело с сокетами, там то заполние буфера не предсказуемо, может заполнится полностью, а может частично.

>>Что значит «для вашего удобства не полностью заполняете буфер»?
например, если вы ложите в буфер какой-то неделимый блок данных, и если не хватает места в буфере, то всегда проще отдать уже то, что есть, и уже на следующем цикле, когда в буфере будет достаточно места, ложить эти данные. Иначе при условии заполнения буфера полностью, может сильно усложнится код
Как у вас в потоке может быть неделимый кусок данных? В том и дело, что на уровне абстракции потока не существует неделимых блоков, есть непрерывный поток байт.

Вы путаете работу с сокетами на самом низком уровне (когда действительно не знаешь сколько прийдет) и на уровне потоков.нет, по сути эти классы потоков и призваны абстрагировать клиентский код от способа получения массива байт, а в этом случае различий для клиента быть просто не должно.
Здесь проблема в том, что вы смешали в кучу аж три уровня абстракции сейчас, уровень имплементации конкретного потока, общий интерфейс потока и клиентский уровень, работающий с данными этого потока.
Вот пример неделимого куска данных:

У вас есть сформированная каким-то образом строка «Это строка которую я сформировал», если в буфере не хватает места для нее, то ее нужно делить и запоминать где поделили, и потом на следующем цикле ложить остаток. Но в реальности намного проще, отдать то что уже положено, и уже на следующем цикле ложить всю строку. В своем коде я столкнулся с таким случаем и бало проще было поступить именно так.
Так можно поступать во внутреннем буфере вашей реализации потока, но при общении с внешним миром — нужно соблюдать интерфейс. Это два разных уровня абстракции. Их недопустимо смешивать.

А приведенный пример — не неделимый кусок данных, и его действительно надо или разрезать и скинуть часть забив буфер до конца, или вообще не скидывать, ожидая прихода других данных и скинуть все скопом под размер буфера. В этом и суть потока. А реализовать это достаточно просто, только держать индекс текущей «головы» в массиве.

Понимаете, зачастую «проще» — совсем не значит «правильно».
Извените, но где я нарушил интерфейс? В МСДН четко написано: конец потока, если Read возратила нуль. А если делать как вы говорите «правильно», то это наделать еще множество новых ошибок и потратить много времени на отладку. И кто вам сказал что вы поступаете правильно?
Я так чисто для любопытства залез в MSDN почитать про StreamReader… вы никогда не задумывались для чего сделано свойство StreamReader.EndOfStream? Угу чтобы не писать ваше индийское while(true) { if-break}…
А если взять в руки reflector и посмотреть на неперегруженную реализацию Read, то можно увидеть что в ней вызывается ReadBuffer а в той в свою очередь — снова этот же Read.

Готов поспорить что в вашем перегруженном методе есть какой-либо косяк который не дает нормально пройти все вызовы…

Но виноват конечно же кривой класс ленимых мелкософтовцев, который лежит в основе огромного количества других классов. И вот у них все хорошо, а вы талант — нашли багу в стримридере.

Давайте компилируемый код «с багой» в перегруженном стримридере в студию и думаю что мы быстро обнаружим у кого и откуда растут руки и.

В общем реквестирую пруфкод на багу в стримридере.
И да… Из мсдн:

This method returns an integer so that it can return 0 if the end of the stream has been reached.

Can — это значит МОЖЕТ вернуть 0, если конец потока достигнут. А не ДОЛЖЕН возвращать 0. А также 0 может вернуться если ничего не прочитали… ну вот застопорился поток, бывает такое, где то байтик застрял и не пролазит сквозь TCP/IP, толстый такой байтик, нестандартный попался…
А правильно проверять окончание потока через StreamReader.EndOfStream — специально выделенное свойство. Вот если в нем true — значит действительно поток кончился. А если не true — то Read может хоть массив нулей возвращать — надо читать пока не будет тру…
В том то и дело что EndOfStream становится равным true, если возратился не полностью заполненный буфер.
Ничего нельзя сказать не имея кода. Реквестирую сорцы.
Забавно видеть такой код после целой группы чудесных статей про ООП и паттерны
А если не обращать внимание на код? Тем более что код писался в основном для тестов
Ну как бы имхо либо код надо отрефакторить и тогда уже делать статью, чтобы кодом хотя бы могли воспользоваться, либо же вообще не прикладывать код, ограничившись графиками, блоксхемами, алгоритмом, выводами. Чисто практической пользы от такого кода для читателей по моему мнению очень мало. Вряд ли он приведет«к большей ясности» =)

По самой идее ничего комментировать не могу, ибо не настолько часто пишу чтото на шарпе и не очень разбираюсь в архитектуре .NET
Как хорошо, что мне не надо поддерживать ваш код.
И не нужно, так как в реальности будет другой ;)
Вы используете C#, будто это чистый С.
Я хочу развидеть это.
В C есть методы, здесь же посредственное использование ассемблера.
С — это хороший, качественный portable assembler :)
В этом его ключевое преимущество.
Да, я просто к тому, что у автора его монстро-метод стоит разбить на несколько маленьких, и хороший программист на C это бы сделал, а на C++ — ещё бы и правильно с классами работал, здесь же нет ни того, ни другого.
Вот именно, так как я в основном работаю на С++, на С# это сильно сказывается
В C++ тоже есть классы, и есть методы, здесь же ни того ни другого, чистый ассемблер.
Видать вы не знаете ассемблера, а я знаю и когда-то много на нем писал :)
здесь же посредственное использование ассемблера.
Хороший программист на ассемблере ещё бы разбил это по «функциям» если их можно конечно так назвать.
Иногда так удобнее
Честно — но это просто смешно, писать на языках высокого уровня весь код в одном методе, с монструозной длиной и кучей уровней вложенности. Если вы считаете это более удобным, то даже видно и доказывать обратное бесполезно.
И кто вам мешает смеятся?
Мешает смеяться мне грусть, от того, что на публичных ресурсах публикуется такой код и такие советы, а потом новички это читают и слепо делают так же.
Уж извините, но вы такой же новичек, так же скажу, что я не теоретик, а практик, а терия очень часто не согласуется с практикой.
Удачи вам судить всех по возрасту, не думайте что из за вашего возраста ваш код станет лучше.
… вылаживать… лишнии… извените… ньюансы… гепотетический… ложить… новичек…
этот список можно продолжить. У вас что, браузер красненьким не подчёркивает ошибки? Или вы потом всё переписываете начисто?
К чему это я, а к тому, что надо сразу писать нормально, а не тратить время на отладку говнокода (которая, по вашим словам, заняла один день) и потом его переписывание.
P.S. Респект VenomBlood за упорство.
Ну куда мне с вами тягаться, лучше бы сначала попробовали что лучшее предложить, точнее реализовать, а VenomBlood я уже говорил, что его способ не решает всех проблем, в частности он не позволяет читать данные порциями
Я уже устал говорить, что решает…
С вами уж точно трудно тягаться, в плане упорства отстаивания качества своего быдлорешения и быдлокода. Главное чтобы не дай бог по работе не пересечься с вашими решениями.
Кроме ваших слов «быдлокод» и «говнокод» я ничего путнего не увидел, одна вода. Меня интересует сам код, если меня не понимают, то я всегда показываю код, который доказывает мою правоту, от вас я не увидел ни строчки кода, хотя сами писали, что так просто, что почти писать не нужно
Да, если вас не понимают и требуют объяснить подробнее — вы показываете код, это абсолютно верно и я это поддерживаю.
Тут же одна маленькая разница — я на вас не работаю, поэтому писать код для задачи, за которую кто-то другой получает деньги — я не собираюсь. Да и вышеописанных советов более чем достаточно для того чтобы понять решение, если вы конечно разбираетесь в ООП и .net в частности, ну или хотя-бы в работающей с XML части BCL.
А по поводу воды — у вас проблема что вы мыслите кодом и не понимаете более абстрактных вещей, такое бывает если не разбираешься в технологии, так что советую почитать книги по .net прежде чем работать с ним (т.б. вы же сами упомянули, что в .net — новичок).
в net я точно не новичок, но вы не видите всей проблемы, и думаете что она легко решается на самом верхнем уровне абстракции. То что вы так упорно отказываетесь от показа небольшого примера вашего решения, только доказывает, что вы не можете решить проблему. И не бойтесь, я ваше решение точно не буду использовать, так как оно не решает моей проблемы. Также не забывайте многие выкладывают свои решения, и не боятся что кто-то будет использовать в коммерческом проекте, тут действует принцип я поделился своим решением, ты поделился своим решением и всем хорошо, не нужно потом заниматься велосипедостроением. Я со многими делюсь и не жадничаю.
Можно и поделиться, но не писать на заказ за бесплатно. Про то что в .net вы новичок — писали, да и по коду очень видно, и по выбору решения, подход совершенно не в стиле .net и C#.

На слабо меня брать не надо, вашу работу я не буду выполнять и думайте что хотите, можете остановитсья на выбранном варианте что я не могу или жмот.
Проблема лежит точно выше потока и выше разбора XML, т.к. ошибка именно в несоответствии XSD, это очевидно. Т.о. необходимо работать на уровне сериализатора.
Я в статье четко написал, в XSD проблему можно решить, но ее я не могу ее решать ее каждый раз, так как не формирую его, я получаю его таким какой он есть. Но изменения в XSD не решают проблему чтения данных порциями.
Я когда-то разве сказал что надо XSD менять? Я сказал только что корень проблемы — несоответствие XSD, чтобы побороть не конкретное несоответствие (менять XSD) — надо работать на уровне сериализации. Ваше вырывание слов из сообщения и свои умозаключения на этот счет (упомянул XSD — значит имеет ввиду надо его менять) — абсолютно неуместны и уже надоели.
Чтение данных порциями также решается на этом уровне, т.к. из потока можно читать порциями, текстридеры и прочее поступают также, работа с xml также осуществляется линейно по файлу, без подгрузки всего файла в память. Подгрузка происходить только при попытке десериализации XML, вот тут и надо работать.
Мы друг друга не понимаем, вот код из статьи:


using( FileStream stream = new FileStream(NameFile) )
{
    XmlSerializer xs = new XmlSerializer(typeof(ImportObject));
    ImportObject obj = (ImportObject)xs.Deserialize(stream);
}


Насколько я понял вы предлагаете контролировать ImportObject, а как насчет контроля Deserialize()? Ведь именно она возвращает данные, и возратить только тогда не только ImportObject правильно отработал, но и stream тоже. Вот тут я не вижу, как вы хотите сделать чтение порциями.
Я же говорил что работать надо на уровне сериализатора:
Проблема лежит точно выше потока и выше разбора XML, т.к. ошибка именно в несоответствии XSD, это очевидно. Т.о. необходимо работать на уровне сериализатора.

Там и будем импортить объекты по одиночке а не скопом.
Нет, не понимаете, Deserialize() читает из потока, когда прочли один объект, то это не значит что поток остановился на начале следующего, также чтобы прочесть дальше, нужно заново прочесть заново начало файла и только потом перейти на начало следующего объекта. Иначе, если поток не в начале файла, то Deserialize() возвратить ошибку.
1) Я говорю о том над чем надо работать, а вы говорите как оно работает сейчас.
2) У меня всё Ок, делаю форматтер, передаю ему поток и в цикле десериализую объекты, после десериализации поток не перематывается и остаётся на позиции после предыдущего объекта.
1) Зачем рабоать над тем что не дает нужные результаты?
2) А теперь скажите как вы определите конец объекта
Не надоело гнуть свою линию? Лучше признаться уже что сделали коряво.
В XML? Если он валидный (а про невалидность ничего небыло сказано) — то просто найдя соответствующий тег, закрывающий данный объект.
Сделано красиво (я про алгоритм, а не код), то что вам не нравится, то это не значит, что коряво. XML как раз невалидный, я уже писал об этом
Где? Написано было что он не соответствовал XSD и был большой по размеру, больше ничего.
если есть тэги которые возращают null, а это не описано в XSD, то где тут валидность?
Валидный XML сам по себе, это вообще никак не связано с XSD.
Ничего красивого в том, чтобы на нижнем уровне подменять пустые теги на непойми-что, заранее зная что подсунуть и какие теги менять, и врать по поводу длины файла. Это не красиво, это, извините — уродство.
У каждого свои вкусы, но это не значит что вы правы.
Вы не замечаете, что ваша фраза оправдывает любой, причем абсолютно любой говнокод и любой ужасный проект. Кроме «вкусов» есть стандарты, есть другие люди, которым с этим работать, и это надо уважать. В конце концов, «свой вкус» не выставляют на публичное осмотрение, делаете чисто по своему — держите при себе.
Причем тут говнокод? Я кстати не видел нигде вашего, не думаю что он лучше моего, но не этого.
Потому что фразой «у каждого свои вкусы» можно оправдать вообще всё, не нравится детское порно? А что — у кого-то такие вкусы, а на законы (читай правила) — они тоже плевали. Так чтоли? Нет, спасибо, не нужно такое счастье. Оставьте свой вкус при себе.
Я и не прошу, просто я лишний раз убедился что ваш метод не решает моей проблемы, и ваше упорстово только доказывает это. На счет net, то знать все не возможно, для этого и существует такие блоги как этот, чтобы люди могли делится своим опытом. Я поделился, вы не хотите, ну и ладно, только пожалуйста, не мешайте делится дальше, путем понижения кармы.
В карму я не лез, в надежде на то, что следующие топики будут адекватными.
Я не говорю что всё знать (хотя базово .net не такой большой) но любой человек обязан знать то, что он сейчас использует. Работаете с XML? Так надо прежде разобраться с тем, как работать с XML в .net. И уж тем более необходимо перед тем как публиковать топик где-то в общедоступном месте.
Я и так разобрался, и мое решение меня вполне удовлетворяет так как позволяет на низком уровне полностью контролировать верхний уровень, а то что код плохой, то это не поменяет сути при написании красивого
Вот! Слава богу что вы это признали.
Теперь перечитайте ещё раз:
так как позволяет на низком уровне полностью контролировать верхний уровень
Вот это и есть грубейшая ошибка, не связанная с качеством кода, но связанная с самой выбранной идеей (подходом), я рад что вы это сами явно указали, и если теперь вы это считаете нормальным — то мне нет смысла разговаривать с вами о программировании вообще и ждать ваших адекватных топиков в частности (пока не научитесь избегать таких ошибок конечно, чего я и желаю вам).
Ну честное слово, детский сад какой-то, как вы не поймете, что на верхнем уровне не все видно, так как все сглажено и лишнее убрано. Приведу пример, когда вы фоткает, то фотик в начале формирует RAW файл, это исходные данные полученные непосредственно из апаратуры, потом они обрабатываются и подаются в виде красивых jpg файлов, где после обработки теряются многие данные. Профессиональные фотографы всегда используют только исходный RAW файл и спецпрогами правят его как они считают нужным. Точно так же и я поступил, что непонятно?
1) У вас нет потери данных на верхем уровне — поэтому замечание непременимо
2) RAW и Jpeg это оба форматы файлов, следовательно находящиеся на 1 уровне абстракции, поэтому замечание непременимо
3) Я уже выделил жирным вашу главную ошибку, нижий уровень не должен контроллировать верхний, а уж в такой грубой форме, как использовано — и подавно. Поэтому замечание непременимо
1) Есть еще какие, так как не вижу тегов и тем более их уровень и последовательность
2)jpg это обработанный RAW, сначала идет RAW (xml файл), потом из него делается jpg (Объект), т. е. jpg это формат который содержит уже обработанную исходную информацию по заданным алгоритмам, так что тут разные уровни
3)Давай пример из политики ;) Президент это верхний уровень, народ избирает президента, значит он уровнем пониже, но при этом он должен контролировать президента, иначе потом верхний уровень пошлет куда подальше верхний, что сейчас и наблюдается в наших странах
1) это пропадает именно на уровне сериализатора, где я и предлагаю работать.
2) Начнем с того, что RAW это формат файлов, и вначале идёт снапшот с матрицы, а потом он уже преобразуется в RAW. Вы ведь не говорите что gif это преобразованный jpg только потому что в нем меньше цветов и его можно в т.ч. получить из jpeg?
3) Боже, какие примеры? Из политики? А может из кулинарии ещё? Это программирование! Такие примеры здесь неуместны.
Точнее сказать RAW это обобщенное название группы форматов.
1) Это не позволяет контролировать оставновку в нужное время
2) RAW это исходный файл в котором все данные в не сжатом и не обработанном виде, gif и jpg это уже сжатые данные с потерями (gif нет потерь, но там проблемы с предствалением множества цветов)
3) Многие вещи, что в политике, что в куналирии имеют похожие связи, просто иногда ими проще доказывать свою правоту
1) А я говорю что позволяет, и описал как это сделать, если у вас не позволяет, ну чтож, у вас свой .net какой-то.
2) Начнем с того, что во всех современных камерах он сжат, и потери есть, т.к. происходит дискретизация данных с матрицы (у RAW тоже есть понятие «глубина цвета»)
3) Не надо приводить примеры из политики, иначе программирование можно будет извратить как угодно и найти подтверждение в политике.
1) Хоть убей, не вижу каким способом
2) Это только доказывает мою правоту
3) Надо и нужно приводить примеры из других областей, так как это помогает осваивать материал
1) Перечитать комменты выше
2) Чем? В RAW файлах данные уже идут с потерями, также как и в JPG, RAW также сжат (как и jpeg) просто алгоритмы разные и в jpeg один алгоритм который выполняет обе задачи (и убирает «лишние» данные и сжимает)
3) Это надо делать с пониманием и очень осторожно, но никак не приводить такие примеры из политики, чтобы оправдать жесткую связанность и нарушение абстракций.
1) Прочтите мои аргументы, которые доказывают вашу не правоту
2) RAW как раз не сжатый, или сжатый без потерь, jpg как раз многое теряет при сжатии
3) Я и делаю с пониманием, и тут никак не нарушается абстрация
Рав тоже сжат с потерями относительно данных с матрицы, т.к. происходит дискретизация, что и есть потери. Так что RAW — данные тоже с потерями.

Я выше написал. Любой контроль снизу того что наверху — это злостное нарушение, ну хоть это то надо знать.
про RAW это не аргумент, так как он получает уже дискретизированные данные, но при этом он сохраняет их такими же, jpg получает именно теже данные, но при этом делает потери.

Насчет контроля снизу, то что делать когде нет возможности изменить верхний уровень? (забудь про Net). И именно контрль снизу позволяет направлять верхний уровень в нужнуб сторону, так в верхний уровень не может учитывать какие-то ньюансы, а доступа к нему нет, тут нет ничего плохохо, и является обычной практикой
Да костыль это называется, а не «обычная практика», костыль.
Если для вас это норма — пожалуйста, только напишите в топике «Я сделал свой костыль» — чтобы новички не дублировали (хотя заглянув в каменты, я надеюсь, они и так не станут повторять эту вакханалию).
Вы предлагаете костыль не лучше. Ладно предлагаю закрыть тему, у нас с вами разные подходы к делу и слишком большая разница в опыте. Вам не нравится мой метод, не используйте, мне не нравится ваш, я его точно не буду использовать.
Предлагаю удалить этот топик, дабы вашей разницей в опыте (в меньшую сторону очевидно) не травмировать случайно сюда заглянувших. Мне не нравится вакханалия с переплетением всех уровней абстракции в один ком и контролем верхнеуровневой логики непонятно откуда снизу через жуткие костыли.
Удалять точно не буду, так как не вы один на свете, и многим это оказалось полезным. А если вам не нравится, то не смотрите, не думаю что вы сделаете лучше
Тем не менее удалили половину, выставляя себя как-бы не при делах?
Вы говорите многим «оказалось»? полезным? Почему тогда оценка отрицательна у топика? Многие — это сколько? И где пруфы что полезно оказалось таки?
Ах, и как красиво было удалить половину топика с описанием и реализацией костылей? Может теперь скажете что ничего этого и небыло? Удалять надо весь топик, а не пытаться таким детским образом сныкать всё и выставить себя невиновным.
Не вам решать кому что полезно, а кому стало полезным, то посчитайте сколько проголосовало за, а те кто против, то они были против кода, но не против метода.
Да откуда вам знать против чего они голосовали? Я например очень часто голосую за только потому, что мне нравится стремление автора, даже если топик неважный.
Да, и можете из этих плюсов вычесть мой голос и записать в минусы в таком случае.
Тогда зачем ставили плюс? И зачем спорили? Ведь благодаря нашему спору, я теперь не могу еще писать, а у меня есть многое чего
Не благодаря спору, а благодаря вашей невежественности и тупому отстаиванию позиции не приводя аргументов. Минусы ставил не я, оценку поставило сообщество (да, и вообще вы ещё в плюсе).

А плюс ставил потому что это хорошо, когда люди делятся своими мыслями, я же изначально не знал что вы абсолютно неприемлете критику, свысока считаете себя, как более старшего, — умнее, и абсолютно не знаете и не хотите знать то, о чем рассказываете.
К сожалению я не телепат.
Странно, у меня сложилось такое же мнение о вас, да и веских доводов не привели, кроме говнокода и быдлкода ничего путнего не увидел. Ладно нужно заканчивать это бесполезный спор, мне уже надоело доказывать, что я не дурак. Пока.
Очень прошу скинуть код, обещаю не публиковать на хабре, но надо показать людям, т.к. дал ссылку уже на топик.
А можете пожалуйста вернуть код, или скинуть в личку, просто показать коллегам)
Sign up to leave a comment.

Articles