forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Библиотеки (http://forum.boolean.name/forumdisplay.php?f=124)
-   -   Lib_resloader - Экономная загрузка ресурсов (http://forum.boolean.name/showthread.php?t=8201)

odd 22.04.2009 08:15

Lib_resloader - Экономная загрузка ресурсов
 
Вложений: 3
Представьте, что перед вами стоит банальная задача: загрузить какой-то текст из файла и отобразить его на экране.
Нет, не надо ломать голову.
Я знаю как вы поступите, готовая программа будет выглядеть примерно так:

PHP код:

Program Res01;
Var    
stempstring;
        
resresource;
        
iinteger;
        
function 
win2utf(sstring): string// Перекодировка из Win-1251 --> UTF-8
var    lenchinteger;
        
tstring;
begin
    t
:=''len:=Length(s)-1;
    for 
i:=0 to len do
    
begin
        ch
:=ord(GetChar(si));
        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:=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. Что и понятно.

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

PHP код:

Program Res02;
Uses resloader;
Var    
stempstring;
        
iinteger;
        
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
    Строка ### понимается как маркер конца файла
    Строка # понимается как знак перевода строки

Как видите, ничего сложного. Всё просто и удобно. Проблема решена.

12121 28.04.2009 13:42

Ответ: Lib_resloader - Экономная загрузка ресурсов
 
А можно добавить загрузку с произвольной строки и загружать определенное количество строк ? Например загрузить 100 строк начиная с 50. Было бы вообще идеально.

12121 28.04.2009 13:45

Ответ: Lib_resloader - Экономная загрузка ресурсов
 
А если файл не найден что будет?

odd 03.05.2009 20:25

Ответ: Lib_resloader - Экономная загрузка ресурсов
 
Вложений: 1
Добавил функцию чтения произвольного количества строк.
Синтаксис новой функции такой:

string ReadLinesBlock(fn: string; start: integer; len: integer; enc: integer)
Читает из файла блок строк.
fn - имя файла (символ "/" в начале имени добавлять не надо)
start - строка с которой нужно начать считывать (счёт идёт с 0, т.е. самая первая строчка в тексте имеет номер 0)
len - количество строк которое нужно считывать
enc - надо ли делать перекодировку из cp1251 --> UTF-8; 1 - надо перекодировать, 0 - не надо

Пример использования в программе:
PHP код:

Program Res02;
Uses resloader;
Var    
stempstring;
        
iinteger;
        
Begin
    s
:=ReadLinesBlock('test.txt'151); // Читаем 5 строк с перекодировкой, причём первую строку пропускаем
    
ShowForm;
    
i:=FormAddString(s);
    
Delay(10000); // Небольшая задержка
End


Winner 19.05.2009 18:21

Ответ: Lib_resloader - Экономная загрузка ресурсов
 
PHP код:

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


Что я сделал не так?

Richik 20.05.2009 01:54

Ответ: Lib_resloader - Экономная загрузка ресурсов
 
Дай кода больше, что до этого у тебя?

Winner 20.05.2009 13:05

Ответ: Lib_resloader - Экономная загрузка ресурсов
 
До этого begin. Ошибка возникла только когда начал читать строку с помощью библиотеки.

var
mas1: array[1..60] of string;

Richik 21.05.2009 12:14

Ответ: Lib_resloader - Экономная загрузка ресурсов
 
OpenRes('123.txt');
for i:=1 to 10 do mas2[i]:=resloader.ReadLine;
closeRes;

Winner 22.05.2009 01:10

Ответ: Lib_resloader - Экономная загрузка ресурсов
 
Спасибо. Работает.

salsero 04.06.2009 17:22

Ответ: 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;


salsero 04.06.2009 17:37

Ответ: Lib_resloader - Экономная загрузка ресурсов
 
Получается, Readline не перекодирует строку. Только loadtext и readlineblocks. A readline надо дополнительно перекодировать функцией. Какой из способов чтения строк тогда будет быстрее?

odd 20.06.2009 01:44

Ответ: Lib_resloader - Экономная загрузка ресурсов
 
Вложений: 1
Цитата:

Сообщение от salsero (Сообщение 106677)
Получается, Readline не перекодирует строку. Только loadtext и readlineblocks. A readline надо дополнительно перекодировать функцией. Какой из способов чтения строк тогда будет быстрее?

Добавил в библиотеку твою функцию. Теперь её можно вызывать как отдельно (ansi2utf) так и автоматически при чтении строки из файла ресурсов (нужно указывать режим перекодировки 2).
Подробности - в файлике с описанием библиотеки

cyberdyne 03.09.2009 17:00

Добрый день, а у меня такая проблемма
вот код
PHP код:

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
(000);
    
FillRect(00GetWidthGetHeight); 
    
DrawImage(logoGetWidth/2-66,GetHeight/2-80);
    
SetColor(25500);
    
DrawText('ОШИБКА!!!', (GetWidth getStringWidth('ОШИБКА!!!'))/2GetHeight-50);
    
repaint;
     
delay(300);
     
end;

begin 

  logo
:= LoadImage('/logo.png');  
  
OpenRes(filik);
    
  
     
id := resloader.ReadLine;
     
CloseRes
 
     
id2:=resloader.win2utf(id);
    
text:=pref+' '+id2
    
SetColor(000);
    
FillRect(00GetWidthGetHeight); 
    
DrawImage(logoGetWidth/2-66,GetHeight/2-80);

    
repaint;
    
delay(100);
    

    if 
not smsStartSend('sms://'+numtextthen error
   
    while 
smsIsSending do // ждём, пока сообщение не будет отправлено 
      
delay(100); 

    if 
not smsWasSuccessfull then error// проверяем, успешно ли было отправлено сообщение 
    
    
delay(200);

  
end

почему то на нокия 2610(топор) работает, а на n79 пишет ошибку о не хватке памяти, тоже самое было до подключения вашей библиотеки, и с ней тоже самое, ничего не могу понять

все вроди норм заработало, правда в чем была ошибка так и не понял

Цитата:

Сообщение от cyberdyne (Сообщение 117455)
все вроди норм заработало, правда в чем была ошибка так и не понял

оказывается в тексте ресурса должно быть более 3 строк минимум 4, я записал 1 строку и 3 enter и все начило работать, почему так -хз

Cliffe Snake 13.09.2009 17:50

Ответ: Lib_resloader - Экономная загрузка ресурсов
 
Хм, win2utf конвертит этот символ ~ в квадратик, остальные не проверял.
Odd, сделай плиз, чтобы можно было обращаться к разным ресурсам по ID.
И замени ReadLine на ReadStr, ато она совпадает со стандартной командой - неудобно.
Типа так:
PHP код:

........
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 удобнее будет, но и так сойдёт. =)

im_zorg 14.05.2010 19:51

Ответ: 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.



Часовой пояс GMT +4, время: 03:08.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot