Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.02.06;
Скачать: CL | DM;

Вниз

Как правильно читать и писать строки в поток?   Найти похожие ветки 

 
Sergey   (2010-11-18 06:41) [0]

Делаю так:


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);


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


 
MBo ©   (2010-11-18 08:20) [1]

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

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


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


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


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

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


 
Rouse_ ©   (2010-11-18 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] будет выход за пределы...


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


> 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 байт были считаны.

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


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


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

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


 
MBo ©   (2010-11-18 16:37) [6]

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

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

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

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


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


> Sergey   (18.11.10 16:29) [4]

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

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

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


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


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


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


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


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


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


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


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

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



Страницы: 1 вся ветка

Текущий архив: 2011.02.06;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.008 c
15-1283595848
Jee
2010-09-04 14:24
2011.02.06
Запустить одну процедуру несколькими потоками


2-1288885183
harisma
2010-11-04 18:39
2011.02.06
Присвоение TField.Value или TField.AsString


3-1251976429
kyn66
2009-09-03 15:13
2011.02.06
После обновления компонентов ADS - ошибка


4-1245062957
василий иванович
2009-06-15 14:49
2011.02.06
самописный CSP


15-1287992249
brother
2010-10-25 11:37
2011.02.06
Пионеры-гоголевцы