Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как правильно читать и писать строки в поток?


Sergey ©   (2010-11-18 06:41:00) 

Делаю так:


var
 k : Integer;

   // Запись.
 s := 'some text';
 k := Length(s);
 aStream.Write(k, 4);
 aStream.Write(s[1], k);

   // Чтение.
 aStream.Read(k, 4);
 SetLength(s, k);
 aStream.Read(s[1], k);


Всегда ли это правильно?


_Юрий   (2010-11-18 18:59:00) [1]


> Обработка какая-то не правильная. Если count = 0 , то не
> надо выдавать никаких ошибок


Согласно приведенному коду, никаких ошибок в случае count = 0 и не будет.


> Если же считали меньше данных, чем в потоке есть, то надо
> вывести окно с тремя кнопками, "повторить", "остановить",
>  "игнорировать".


Представим себе ситуацию: код выполняется на сервере в режиме сервера. То есть, никакого пользователя нет, а просто обрабатывается запрос клиентской программы. Возникла такая ситуация.
И кто будет нажимать на кнопку? Пока не нажали, поток стоит, клиент считает, что сервер завис (по сути, так и есть).


> Если повторить, то значит попытаться дочитать необходимые
> данные, если игнорировать, то сделать вид, что всё считано
> нормально, если остановить, то тогда уж и генерировать исключение.
>

А пользователь то откуда знает, можно ли игнорировать эту ошибку и что у вас в стриме записано?


Сергей М.   (2010-11-18 17:43:00) [2]


> Sergey   (18.11.10 16:29) [4]

> Обработка какая-то не правильная

Обработка правильная, не надо нести околесицу.
Это у тебя с головой или с логикой в ней неправильно)

Не хочешь исключений, подсказывающих тебе о проблеме ?
Да пользуй на здоровье свои Read/Write, никто не возражает.
Но тогда и не пеняй впоследствии на кривые винду и дельфу, коли ты никакне реагируя на возвращаемые ими результаты рано или поздно получишь за это граблями)


> 2010 и XE. Какую лучше выбрать?


Ты в этой-то хотя бы разберись)
А в этой "плаваешь", а туда же - лыжи мылишь в ощутимо более сложные продукты )


MBo   (2010-11-18 16:37:00) [3]

>А если длина строки больше 255, то не будет выхода за пределы?
>Я так понимаю, что строка - это массив символов, в нулевом элементе которого записана длина s[0]. А элемент - это байт.

Это строки ShortString так устроены, которые теперь применяются только по особому поводу.
А string по умолчанию  - длинные, =  Ansistring в D2-2007, или юникодные в 2009+

>У них dcu совместимы с Дельфи 7?
dcu несовместимы ни для каких версий Дельфи

>2010 и XE. Какую лучше выбрать?
наверно, XE  - там часть ошибок поправили, внесли другие ;), но все равно она поновее.
Но если нет реальной потребности в переходе, то D7 куда стабильнее, да и хелп там настоящий имеется.


Германн   (2010-11-18 16:36:00) [4]


> А если длина строки больше 255, то не будет выхода за пределы?
>
> Я так понимаю, что строка - это массив символов, в нулевом
> элементе которого записана длина s[0]. А элемент - это байт.
>
>

Такие строки уже давно не встречаются.


Sergey   (2010-11-18 16:29:00) [5]


> Rouse_ ©   (18.11.10 12:21) [3]
>
> Вот тут не правильно:
> aStream.Read(s[1], k);
>
> надо переписать вот так:
>
> aStream.ReadBuffer(k, 4);
> SetLength(s, k);
> if k > 0 then
>   aStream.ReadBuffer(s[1], k);
> В противном случае если длина строки нулевая то при вызове
> s[1] будет выход за пределы...


А если длина строки больше 255, то не будет выхода за пределы?
Я так понимаю, что строка - это массив символов, в нулевом элементе которого записана длина s[0]. А элемент - это байт.


> MBo ©   (18.11.10 08:20) [1]
>
> aStream.Read(k, SizeOf(Integer));
> SetLength(s, k);
> aStream.Read(PChar(s)^, k * SizeOf(Char));
>
> SizeOf(Char) существенно, т.к. в последних версиях Дельфи
> строки по умолчанию юникодные.


Кстати, присматриваюсь к последним версиям Дельфи. 2010 и XE. Какую лучше выбрать? У них dcu совместимы с Дельфи 7? Или в случае использования двух Дельфи на одном компьютере надо будет каждый раз всё перекомпилировать?


> Сергей М. ©   (18.11.10 09:56) [2]
>
>
> > Всегда ли это правильно?
>
>
> Нет, не всегда.
>
> Всегда правильным будет использование методов Read/WriteBuffer.
>
> Методы Read/Write не сообщат об ошибках, если таковые по
> каким-либо причинам возникнут в ходе поточного чтения/записи,
>  при условии что результаты вызовов этих методов ты напрочь
> игнорируешь.


Код в Classes такой:

procedure TStream.ReadBuffer(var Buffer; Count: Longint);
begin
 if (Count <> 0) and (Read(Buffer, Count) <> Count) then
   raise EReadError.CreateRes(@SReadError);
end;


Обработка какая-то не правильная. Если count = 0 , то не надо выдавать никаких ошибок, а просто не надо ничего считывать из потока, а сделать вид, как будто бы 0 байт были считаны.

Если же считали меньше данных, чем в потоке есть, то надо вывести окно с тремя кнопками, "повторить", "остановить", "игнорировать". Если повторить, то значит попытаться дочитать необходимые данные, если игнорировать, то сделать вид, что всё считано нормально, если остановить, то тогда уж и генерировать исключение.


Rouse_   (2010-11-18 12:21:00) [6]

Вот тут не правильно:
aStream.Read(s[1], k);

надо переписать вот так:

aStream.ReadBuffer(k, 4);
SetLength(s, k);
if k > 0 then
  aStream.ReadBuffer(s[1], k);

В противном случае если длина строки нулевая то при вызове s[1] будет выход за пределы...


Сергей М.   (2010-11-18 09:56:00) [7]


> Всегда ли это правильно?


Нет, не всегда.

Всегда правильным будет использование методов Read/Write Buffer.
Методы Read/Write не сообщат об ошибках, если таковые по каким-либо причинам возникнут в ходе поточного чтения/записи, при условии что результаты вызовов этих методов ты напрочь игнорируешь.


MBo   (2010-11-18 08:20:00) [8]

aStream.Read(k, SizeOf(Integer));
SetLength(s, k);
aStream.Read(PChar(s)^, k * SizeOf(Char));

SizeOf(Char) существенно, т.к. в последних версиях Дельфи строки по умолчанию юникодные.


Наверх

Титульная страница Поиск, карта сайта Написать письмо