|
22.04.2009, 08:15
|
#1
|
Мастер
Регистрация: 06.09.2007
Адрес: Донецк, ДНР
Сообщений: 1,023
Написано 298 полезных сообщений (для 713 пользователей)
|
Lib_resloader - Экономная загрузка ресурсов
Представьте, что перед вами стоит банальная задача: загрузить какой-то текст из файла и отобразить его на экране.
Нет, не надо ломать голову.
Я знаю как вы поступите, готовая программа будет выглядеть примерно так:
Program Res01; Var s, temp: string; res: resource; i: integer; function win2utf(s: string): string; // Перекодировка из Win-1251 --> UTF-8 var len, ch: integer; t: string; begin t:=''; len:=Length(s)-1; for i:=0 to len do begin ch:=ord(GetChar(s, i)); if ch>122 then t:=t+chr(ch+1104); else t:=t+chr(ch); end; win2utf:=t; end; Begin s:=''; res:=OpenResource('/test.txt'); repeat temp:=ReadLine(res); if temp='###' then break; s:=s + win2utf(temp) + chr(10); until false; CloseResource(res); ShowForm; i:=FormAddString(s); Delay(10000); // Небольшая задержка End.
А как вы думаете, много памяти тратится при чтении файла?
Я сделал простой тест. Загрузил файл размером 1024 байта (1 Кб) с 32 строками русского текста.
После запуска эмулятор WTK 2.5.2 мне выдал такой график:
Поясню график. Я запускал программу 2 раза. В первом случае до запуска программы памяти занято было 67500 байт, после запуска - 595124 байт, разница - 527624 байт. Во втором случае до запуска было 73256 байт, а после запуска - 540752 байт, разница - 467496 байт. То есть выходит, что на чтение файла размером 1Кб уходит до 515Кб памяти (!!!), а не каждый телефон может себе такое позволить. При тестировании на реальных телефонах (слабенькие Nokia, типа n7390 и проч.) вылетала ошибка Out of memory. Что и понятно.
Естественно, такое положение дел меня возмутило и я создал небольшую библиотеку для загрузки текста из файла.
Исходный код теперь заметно упростился:
Program Res02; Uses resloader; Var s, temp: string; i: integer; Begin s:=LoadText('test.txt'); ShowForm; i:=FormAddString(s); Delay(10000); // Небольшая задержка End.
Но что же покажет тест?
После теста имеем такие показатели:
В цифрах это выглядит так:
Первый запуск: 88420 - 67520 = 20900 байт.
Второй запуск: 90056 - 75448 = 14608 байт.
Разница очевидна. В первом примере тратилось до 515Кб памяти, а во втором менее 20Кб.
Библиотека имеет команды сходные со стандартными:
OpenRes(f: string) - Открыть текстовый ресурс (символ "/" к имени добавлять не надо)
f - имя файла
CloseRes - Закрыть ресурс
string ReadLine - прочитать строку из ресурса
string ReadByte - прочитать байт из ресурса
string win2utf(s: string) - Перекодировка текста из кодировки cp1251(Windows) в UTF-8
string LoadText(f: string) - Загрузка текста
f - имя файла (символ "/" к имени добавлять не надо)
При чтении проходит автоматическая перекодировка строк из cp1251 в UTF-8
Строка ### понимается как маркер конца файла
Строка # понимается как знак перевода строки
Как видите, ничего сложного. Всё просто и удобно. Проблема решена.
|
(Offline)
|
|
Эти 11 пользователя(ей) сказали Спасибо odd за это полезное сообщение:
|
Amigo888 (15.01.2012), Android (21.05.2010), Cliffe Snake (18.05.2009), GRAY_WOLF (24.04.2009), NetBuilding (18.06.2010), Pyth_ON (15.05.2010), Romanzes (22.04.2009), Skythrone (24.04.2009), SmAlViK (07.05.2009), VM (22.04.2009), Winner (19.05.2009)
|
28.04.2009, 13:42
|
#2
|
Нуждающийся
Регистрация: 26.12.2008
Сообщений: 57
Написано 22 полезных сообщений (для 28 пользователей)
|
Ответ: Lib_resloader - Экономная загрузка ресурсов
А можно добавить загрузку с произвольной строки и загружать определенное количество строк ? Например загрузить 100 строк начиная с 50. Было бы вообще идеально.
|
(Offline)
|
|
28.04.2009, 13:45
|
#3
|
Нуждающийся
Регистрация: 26.12.2008
Сообщений: 57
Написано 22 полезных сообщений (для 28 пользователей)
|
Ответ: Lib_resloader - Экономная загрузка ресурсов
А если файл не найден что будет?
|
(Offline)
|
|
03.05.2009, 20:25
|
#4
|
Мастер
Регистрация: 06.09.2007
Адрес: Донецк, ДНР
Сообщений: 1,023
Написано 298 полезных сообщений (для 713 пользователей)
|
Ответ: Lib_resloader - Экономная загрузка ресурсов
Добавил функцию чтения произвольного количества строк.
Синтаксис новой функции такой:
string ReadLinesBlock(fn: string; start: integer; len: integer; enc: integer)
Читает из файла блок строк.
fn - имя файла (символ "/" в начале имени добавлять не надо)
start - строка с которой нужно начать считывать (счёт идёт с 0, т.е. самая первая строчка в тексте имеет номер 0)
len - количество строк которое нужно считывать
enc - надо ли делать перекодировку из cp1251 --> UTF-8; 1 - надо перекодировать, 0 - не надо
Пример использования в программе:
Program Res02; Uses resloader; Var s, temp: string; i: integer; Begin s:=ReadLinesBlock('test.txt', 1, 5, 1); // Читаем 5 строк с перекодировкой, причём первую строку пропускаем ShowForm; i:=FormAddString(s); Delay(10000); // Небольшая задержка End.
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо odd за это полезное сообщение:
|
|
19.05.2009, 18:21
|
#5
|
Нуждающийся
Регистрация: 28.09.2008
Сообщений: 98
Написано одно полезное сообщение
|
Ответ: Lib_resloader - Экономная загрузка ресурсов
openRes('data.txt'); for i:=1 to 10 do mas2[i]:=ReadLine; closeRes;
Ошибки:
error, character '(' expected, ';' found
error, indentifier 'closeRes' is not constant, function or variable name
Что я сделал не так?
|
(Offline)
|
|
20.05.2009, 01:54
|
#6
|
Нуждающийся
Регистрация: 02.05.2009
Сообщений: 68
Написано 6 полезных сообщений (для 6 пользователей)
|
Ответ: Lib_resloader - Экономная загрузка ресурсов
Дай кода больше, что до этого у тебя?
|
(Offline)
|
|
20.05.2009, 13:05
|
#7
|
Нуждающийся
Регистрация: 28.09.2008
Сообщений: 98
Написано одно полезное сообщение
|
Ответ: Lib_resloader - Экономная загрузка ресурсов
До этого begin. Ошибка возникла только когда начал читать строку с помощью библиотеки.
var
mas1: array[1..60] of string;
|
(Offline)
|
|
21.05.2009, 12:14
|
#8
|
Нуждающийся
Регистрация: 02.05.2009
Сообщений: 68
Написано 6 полезных сообщений (для 6 пользователей)
|
Ответ: Lib_resloader - Экономная загрузка ресурсов
OpenRes('123.txt');
for i:=1 to 10 do mas2[i]:=resloader.ReadLine;
closeRes;
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
22.05.2009, 01:10
|
#9
|
Нуждающийся
Регистрация: 28.09.2008
Сообщений: 98
Написано одно полезное сообщение
|
Ответ: Lib_resloader - Экономная загрузка ресурсов
Спасибо. Работает.
|
(Offline)
|
|
04.06.2009, 17:22
|
#10
|
AnyKey`щик
Регистрация: 04.06.2009
Сообщений: 2
Написано 0 полезных сообщений (для 0 пользователей)
|
Ответ: Lib_resloader - Экономная загрузка ресурсов
Подскажите, плиз, почему не работает ни "неправильный вариант" в 1 пункте, ни Эта либа. Русский текст показывает только с такой функцией:
function ansi(str : string) : string;
var {rus_ansi to unicode}
s : string;
i,c : integer;
begin
s := '';
for i := 0 to length(str)-1 do
begin
c := ord(getChar(str,i)) and 255;
if (c>=192) then c := c+(1040-192) else
if (c<32) and (c<>10) then c := 32;
s := s+chr(c);
end;
ansi := s;
end;
|
(Offline)
|
|
04.06.2009, 17:37
|
#11
|
AnyKey`щик
Регистрация: 04.06.2009
Сообщений: 2
Написано 0 полезных сообщений (для 0 пользователей)
|
Ответ: Lib_resloader - Экономная загрузка ресурсов
Получается, Readline не перекодирует строку. Только loadtext и readlineblocks. A readline надо дополнительно перекодировать функцией. Какой из способов чтения строк тогда будет быстрее?
|
(Offline)
|
|
20.06.2009, 01:44
|
#12
|
Мастер
Регистрация: 06.09.2007
Адрес: Донецк, ДНР
Сообщений: 1,023
Написано 298 полезных сообщений (для 713 пользователей)
|
Ответ: Lib_resloader - Экономная загрузка ресурсов
Сообщение от salsero
Получается, Readline не перекодирует строку. Только loadtext и readlineblocks. A readline надо дополнительно перекодировать функцией. Какой из способов чтения строк тогда будет быстрее?
|
Добавил в библиотеку твою функцию. Теперь её можно вызывать как отдельно (ansi2utf) так и автоматически при чтении строки из файла ресурсов (нужно указывать режим перекодировки 2).
Подробности - в файлике с описанием библиотеки
|
(Offline)
|
|
03.09.2009, 17:00
|
#13
|
AnyKey`щик
Регистрация: 03.09.2009
Сообщений: 11
Написано 0 полезных сообщений (для 0 пользователей)
|
Добрый день, а у меня такая проблемма
вот код
program sms; Uses resloader; const num='00000000'; pref='халоу пиплы'; filik='data.txt'; var res : resource; nomer : integer; id2,id,text : string; logo1 : image; logo : image; procedure error; begin SetColor(0, 0, 0); FillRect(0, 0, GetWidth, GetHeight); DrawImage(logo, GetWidth/2-66,GetHeight/2-80); SetColor(255, 0, 0); DrawText('ОШИБКА!!!', (GetWidth - getStringWidth('ОШИБКА!!!'))/2, GetHeight-50); repaint; delay(300); end; begin logo:= LoadImage('/logo.png'); OpenRes(filik); id := resloader.ReadLine; CloseRes; id2:=resloader.win2utf(id); text:=pref+' '+id2; SetColor(0, 0, 0); FillRect(0, 0, GetWidth, GetHeight); DrawImage(logo, GetWidth/2-66,GetHeight/2-80); repaint; delay(100); if not smsStartSend('sms://'+num, text) then error; while smsIsSending do // ждём, пока сообщение не будет отправлено delay(100); if not smsWasSuccessfull then error; // проверяем, успешно ли было отправлено сообщение delay(200); end.
почему то на нокия 2610(топор) работает, а на n79 пишет ошибку о не хватке памяти, тоже самое было до подключения вашей библиотеки, и с ней тоже самое, ничего не могу понять
все вроди норм заработало, правда в чем была ошибка так и не понял
Сообщение от cyberdyne
все вроди норм заработало, правда в чем была ошибка так и не понял
|
оказывается в тексте ресурса должно быть более 3 строк минимум 4, я записал 1 строку и 3 enter и все начило работать, почему так -хз
Последний раз редактировалось ViNT, 04.09.2009 в 01:13.
|
(Offline)
|
|
13.09.2009, 17:50
|
#14
|
Нуждающийся
Регистрация: 22.09.2008
Сообщений: 74
Написано 8 полезных сообщений (для 12 пользователей)
|
Ответ: Lib_resloader - Экономная загрузка ресурсов
Хм, win2utf конвертит этот символ ~ в квадратик, остальные не проверял.
Odd, сделай плиз, чтобы можно было обращаться к разным ресурсам по ID.
И замени ReadLine на ReadStr, ато она совпадает со стандартной командой - неудобно.
Типа так:
........ OpenRes(1,'List_obj.txt'); while txt<>'end' do begin txt:=readStr(1); OpenRes(2,txt+'.obj'); while txt2<>'end' do begin txt2:=readStr(2); ......... end; closeRes(2); end; CloseRes(1); .......
Конечно, с текстовым ID удобнее будет, но и так сойдёт. =)
Последний раз редактировалось Cliffe Snake, 13.09.2009 в 18:03.
|
(Offline)
|
|
14.05.2010, 19:51
|
#15
|
Знающий
Регистрация: 25.10.2009
Сообщений: 338
Написано 53 полезных сообщений (для 61 пользователей)
|
Ответ: Lib_resloader - Экономная загрузка ресурсов
Почему при запуске сразу-же выкидывает?
Program wiki;
uses text,resloader;
var
s:string;
key:integer;
Begin
s:=ReadLinesBlock('wiki.txt', 1, 5, 1);
text.init;
text.set_text_par(0, 0, 128, 160, 1, 0, 0, 0, s);
repeat
key:=keytoaction(getkeypressed);
if key=GA_UP then text.mode_up;
if key=GA_DOWN then text.mode_down;
setColor(0,0,0);
text.draw_mult_str;
Repaint;
delay(50);
setColor(0,255,0);
fillRect(0,0,GetWidth,GetHeight);
until false;
End.
|
(Offline)
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 18:12.
|