Як правильно читати і писати рядки в потік

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

# XA0; # XA0; // Читання.
# XA0; aStream.Read (k, 4);

# XA0; SetLength (s, k);
# XA0; aStream.Read (s [1], k);

Чи завжди це правильно?

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

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


> Чи завжди це правильно?

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

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

треба переписати ось так:

aStream.ReadBuffer (k, 4);
SetLength (s, k);
if k> 0 then
# XA0; aStream.ReadBuffer (s [1], k);
В іншому випадку якщо довжина рядка нульова то при виклику s [1] буде вихід за межі.

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

Код в Classes такий:

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

Обробка якась неправильна. Якщо count = 0. то не треба видавати ніяких помилок, а просто не треба нічого зчитувати з потоку, а зробити вигляд, ніби 0 байт були лічені.

Якщо ж вважали менше даних, ніж в потоці є, то треба вивести вікно з трьома кнопками, "повторити", "зупинити", "ігнорувати". Якщо повторити, то значить спробувати дочитати необхідні дані, якщо ігнорувати, то зробити вигляд, що все лічено нормально, якщо зупинити, то тоді вже й генерувати виняток.


> А якщо довжина рядка більше 255, то не буде виходу за межі?
>
> Я так розумію, що рядок - це масив символів, в нульовому
> Елементі якого записана довжина s [0]. А елемент - це байт.
>
>

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

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

> У них dcu сумісні з Дельфі 7?
dcu несумісні ні для яких версій Дельфі


> Sergey # XA0; (18.11.10 16:29) [4]

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

Обробка правильна, не треба говорити нісенітниці.
Це у тебе з головою або з логікою в ній неправильно)

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

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


> Обробка якась неправильна. Якщо count = 0. щось не
> Треба видавати ніяких помилок

Відповідно до наведеного коду, ніяких помилок у разі count = 0 і не буде.


> Якщо ж вважали менше даних, ніж в потоці є, то треба
> Вивести вікно з трьома кнопками, "повторити", "зупинити",
> # XA0; "ігнорувати".

Уявімо собі ситуацію: код виконується на сервері в режимі сервера. Тобто, ніякого користувача немає, а просто обробляється запит клієнтської програми. Виникла така ситуація.
І хто буде натискати на кнопку? Ще не натиснули, потік варто, клієнт вважає, що сервер завис (по суті, так і є).


> Якщо повторити, то значить спробувати дочитати необхідні
> Дані, якщо ігнорувати, то зробити вигляд, що все лічено
> Нормально, якщо зупинити, то тоді вже й генерувати виняток.
>

А користувач то звідки знає, чи можна ігнорувати цю помилку і що у вас в Стрімі записано?

Пам'ять: 0.75 MB
Час: 0.037 c

Схожі статті