Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Lazarus, Free Pascal, CodeTyphon
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.05.2023, 11:10   #11
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,532
По умолчанию

Цитата:
что для чтения больших объемов данных не очень хорошо подходит
для чтения больших объемов не подходит ЧАСТОЕ выделение памяти
что в TStringList без использования capacity
что в динамическом массиве с последовательным увеличением размера
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 18.05.2023, 16:50   #12
mixer12
Пользователь
 
Регистрация: 07.05.2023
Сообщений: 12
По умолчанию

evg_m,
Привет, не мог бы ты мне по этим моментам больше инфы дать?? Я только изучаю freepascal)
mixer12 вне форума Ответить с цитированием
Старый 19.05.2023, 09:30   #13
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,532
По умолчанию

1. частое выделение возрастающих объемов памяти ( с возвратом ) приводит к фрагментации свободной памяти (есть много мелких кусочков, но нет одного большого).
и настанет время, что аппетит (запрос памяти) превысит размер самого большого свободного (out of memory).
поэтому всего лучше просить память сразу(один раз) побольше, а потом неиспользованную память можно вернуть (обрезать).
если не хватит можно конечно попросить еще, но опять же с новым запасом.

2. выделение памяти достаточно медленное действие, а значит замедляет работу программы.
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 22.05.2023, 23:47   #14
mixer12
Пользователь
 
Регистрация: 07.05.2023
Сообщений: 12
По умолчанию

Код:
begin                                                                                                                                                                 
 Scan('/home/oem/Project/Log',Paths);                                                                                                                                  
 Assign(file2,'out.txt');             (файл в который записываются прочитанные данные)                                                                                                                                              
 Rewrite(file2);                                                                                                                                                       
 Close(file2);                                                                                                                                                         
 for i:= Low(Paths) to High(Paths) do    ( массив в котором хранятся пути к файлам которые нужно прочитать)                                                                                                                          
       begin                                                                                                                                                           
       Assign (file1,Paths[i]);                                                                                                                                        
       Reset(file1);                                                                                                                                                   
       while not eof(file1) do                                                                                                                                         
       readln(file1,s2);                                                                                                                                               
Append(file2);                                                                                                                                                        
 writeln(file2,s2);                                                                                                                                                    
 Close(file2);                                                                                                                                                         
 Close(file1);                                                                                                                                                         
 end;                                                                                                                                                                  
 SetLength(Paths, 0);                                                                                                                                                  
 end.
Ребята может кто подскажет ошибку, читаю файлы, но у меня тупо пустые стоки в выходной файл идут
mixer12 вне форума Ответить с цитированием
Старый 23.05.2023, 01:02   #15
jillitil
Форумчанин
 
Аватар для jillitil
 
Регистрация: 17.10.2018
Сообщений: 184
Сообщение

Чтоб понять ошибку, надо знать что ожидалось получить. Может у вас всё работает?

Код:
    Assign(file2, 'out.txt');
    Rewrite(file2);                          //  <-- Создали файл, очистили содержимое
    Close(file2);                            //  <-- u разу его закрыли. Коварный план?
                                             //  Очень коварный план!

    FOR i := Low(Paths) TO High(Paths) DO BEGIN
        Assign(file1, Paths[i]);
        Reset(file1);                        //  <-- Открываете найденый файл для чтения

        WHILE NOT Eof(file1) DO
            Readln(file1, s2);               //  <-- бестолку считывается файл до конца, вероятно в строковую переменную "S2"
                                             // Причём если последняя строка пустая, то и S2 = "";

        Append(file2);                       //  <-- заново открываете выходной файл для дозаписи
        Writeln(file2, s2);                  //  <-- пишете последнюю строку "S2" из входного файла. Не исключено что пишете "ничего"
        Close(file2);
        Close(file1);
    END;
    SetLength(Paths, 0);                     //  <-- Освободили ОЗУ.
Если план был записать содержимое всех найденных файлов в один, то можно попробовать так:
Код:
VAR
    TextFileOutput,TextFileInput: Text;
...
BEGIN
...
    Assign (TextFileOutput, 'out.txt');
    Rewrite(TextFileOutput);

    FOR i := Low(Paths) TO High(Paths) DO BEGIN
        Assign(TextFileInput, Paths[i]);
        Reset (TextFileInput);

        WHILE NOT EOF(TextFileInput) DO BEGIN  
            Readln (TextFileInput, S);
            Writeln(TextFileOutput, S);
        END;

        Close(TextFileInput);
    END;

    Close(TextFileOutput);
    SetLength(Paths, 0);
END;
Естественно надо доделать проверку на открытие или обработку исключений, иначе программа будет "падать" при невозможности открыть файл для чтения/записи.
jillitil вне форума Ответить с цитированием
Старый 23.05.2023, 10:59   #16
mixer12
Пользователь
 
Регистрация: 07.05.2023
Сообщений: 12
По умолчанию

Цитата:
Сообщение от jillitil Посмотреть сообщение
Чтоб понять ошибку, надо знать что ожидалось получить. Может у вас всё работает?

Код:
    Assign(file2, 'out.txt');
    Rewrite(file2);                          //  <-- Создали файл, очистили содержимое
    Close(file2);                            //  <-- u разу его закрыли. Коварный план?
                                             //  Очень коварный план!

    FOR i := Low(Paths) TO High(Paths) DO BEGIN
        Assign(file1, Paths[i]);
        Reset(file1);                        //  <-- Открываете найденый файл для чтения

        WHILE NOT Eof(file1) DO
            Readln(file1, s2);               //  <-- бестолку считывается файл до конца, вероятно в строковую переменную "S2"
                                             // Причём если последняя строка пустая, то и S2 = "";

        Append(file2);                       //  <-- заново открываете выходной файл для дозаписи
        Writeln(file2, s2);                  //  <-- пишете последнюю строку "S2" из входного файла. Не исключено что пишете "ничего"
        Close(file2);
        Close(file1);
    END;
    SetLength(Paths, 0);                     //  <-- Освободили ОЗУ.
Если план был записать содержимое всех найденных файлов в один, то можно попробовать так:
Код:
VAR
    TextFileOutput,TextFileInput: Text;
...
BEGIN
...
    Assign (TextFileOutput, 'out.txt');
    Rewrite(TextFileOutput);

    FOR i := Low(Paths) TO High(Paths) DO BEGIN
        Assign(TextFileInput, Paths[i]);
        Reset (TextFileInput);

        WHILE NOT EOF(TextFileInput) DO BEGIN  
            Readln (TextFileInput, S);
            Writeln(TextFileOutput, S);
        END;

        Close(TextFileInput);
    END;

    Close(TextFileOutput);
    SetLength(Paths, 0);
END;
Естественно надо доделать проверку на открытие или обработку исключений, иначе программа будет "падать" при невозможности открыть файл для чтения/записи.
Задравствуйте, спасибо, что ответили, да, идея такая в массиве содержаться пути к файлам, мне их все нужно по очереди прочитать и записать в один файл, и тут я запутался)
mixer12 вне форума Ответить с цитированием
Старый 25.05.2023, 18:20   #17
mixer12
Пользователь
 
Регистрация: 07.05.2023
Сообщений: 12
По умолчанию

Всем привет! Ребята может кто даст инфы, хочу сделать проверки в своей программе:
Открылся файл
Существует ли файл
Не равен ли файл 0 байт
Все файлы тхт
Вот у меня такой вопрос, если срабатывает какое то условие при проверке вышеперечисленных пунктов, как сделать так что бы программа не останавливала работу а просто пропускала этот файл ( т.е начинала читать следующий файл) может кто то даст пример кода.
mixer12 вне форума Ответить с цитированием
Старый 26.05.2023, 02:49   #18
jillitil
Форумчанин
 
Аватар для jillitil
 
Регистрация: 17.10.2018
Сообщений: 184
Сообщение

Если входной файл открыть в исключительном режиме - это значит ни одна другая программа его не держит открытым.
Остальные проверки банальны.
Код:
FUNCTION OpenFileStreamForMe(VAR FS: TFileStream; CONST FNameStr: STRING): BOOLEAN;
BEGIN
    Result := False;
    IF UpperCase(ExtractFileExt(FNameStr)) <> '.TXT' THEN Exit;
//  IF NOT FileExists(FNameStr) THEN Exit;  // лишнее (но быстрее), т.к. при открытии отсутствующего Ф. выпадет исключение.
    IF Assigned(FS) THEN FreeAndNil(FS);
    TRY
        FS := TFileStream.Create(FNameStr, fmOpenRead OR fmShareExclusive);
        IF FS.Size = 0 THEN
            Raise Exception.CreateFmt('File "%s" is empty.', [FNameStr]);
    EXCEPT
        ON E: Exception DO BEGIN
            WriteLn('ERROR: ', E.Message);
            FreeAndNil(FS);
            Exit;
        END;
    END;
    Result := True;
END;

VAR
    i: Integer;
    Fin, Fout: TFileStream;
    FileList: Array of string;
BEGIN
    SetLength(FileList, 10);
    FileList[1] := 'T:\21.TXT';
    FileList[2] := 'T:\22.TXT';
    FileList[3] := 'T:\23.TXT';
    FileList[4] := 'T:\20.TXT';

    Fout:= TFileStream.Create('T:\OUTPUT.TXT', fmCreate OR fmOpenWrite OR fmShareExclusive);
    FOR i := Low(FileList) TO High(FileList) DO
        IF OpenFileStreamForMe(Fin, FileList[i]) THEN
            Fout.CopyFrom(Fin, Fin.Size)
        ELSE
            WriteLn('  Can''t copy file: "', FileList[i], '"');

    FreeAndNil(Fin);
    FreeAndNil(Fout);
    ReadLn;
END.
jillitil вне форума Ответить с цитированием
Старый 26.05.2023, 22:46   #19
mixer12
Пользователь
 
Регистрация: 07.05.2023
Сообщений: 12
По умолчанию

Цитата:
Сообщение от jillitil Посмотреть сообщение
Если входной файл открыть в исключительном режиме - это значит ни одна другая программа его не держит открытым.
Остальные проверки банальны.
Код:
FUNCTION OpenFileStreamForMe(VAR FS: TFileStream; CONST FNameStr: STRING): BOOLEAN;
BEGIN
    Result := False;
    IF UpperCase(ExtractFileExt(FNameStr)) <> '.TXT' THEN Exit;
//  IF NOT FileExists(FNameStr) THEN Exit;  // лишнее (но быстрее), т.к. при открытии отсутствующего Ф. выпадет исключение.
    IF Assigned(FS) THEN FreeAndNil(FS);
    TRY
        FS := TFileStream.Create(FNameStr, fmOpenRead OR fmShareExclusive);
        IF FS.Size = 0 THEN
            Raise Exception.CreateFmt('File "%s" is empty.', [FNameStr]);
    EXCEPT
        ON E: Exception DO BEGIN
            WriteLn('ERROR: ', E.Message);
            FreeAndNil(FS);
            Exit;
        END;
    END;
    Result := True;
END;

VAR
    i: Integer;
    Fin, Fout: TFileStream;
    FileList: Array of string;
BEGIN
    SetLength(FileList, 10);
    FileList[1] := 'T:\21.TXT';
    FileList[2] := 'T:\22.TXT';
    FileList[3] := 'T:\23.TXT';
    FileList[4] := 'T:\20.TXT';

    Fout:= TFileStream.Create('T:\OUTPUT.TXT', fmCreate OR fmOpenWrite OR fmShareExclusive);
    FOR i := Low(FileList) TO High(FileList) DO
        IF OpenFileStreamForMe(Fin, FileList[i]) THEN
            Fout.CopyFrom(Fin, Fin.Size)
        ELSE
            WriteLn('  Can''t copy file: "', FileList[i], '"');

    FreeAndNil(Fin);
    FreeAndNil(Fout);
    ReadLn;
END.
Код:

program oshi;                                                                                                                                                         
                                                                                                                                                                        
  {$MODE OBJFPC}                                                                                                                                                        
                                                                                                                                                                        
  uses SysUtils;                                                                                                                                                        
  var                                                                                                                                                                   
  file1:text;                                                                                                                                                     
  s1:string;                                                                                                                                                            
                                                                                                                                                                        
 begin                                                                                                                                                                 
 Assign(file1, 'test.txt');                                                                                                                                            
 try                                                                                                                                                                   
 Reset(file1);                                                                                                                                                         
    while not eof(file1) do                                                                                                                                            
       begin                                                                                                                                                           
    readln(file1,s1);                                                                                                                                                  
    writeln(s1);                                                                                                                                                       
       end;                                                                                                                                                            
Close(file1);                                                                                                                                                         
except                                                                                                                                                                
on E:Exception do                                                                                                                                                                                                                                                                                                                    
writeln('файла нет: ' ,E.Message);                                                                                                                                    
 end;                                                                                                                                                                       
end.
А как вам такой вариант???
mixer12 вне форума Ответить с цитированием
Старый 27.05.2023, 00:04   #20
jillitil
Форумчанин
 
Аватар для jillitil
 
Регистрация: 17.10.2018
Сообщений: 184
Сообщение

Вы же сами просили проверку четырёх условий:
Цитата:
Сообщение от mixer12 Посмотреть сообщение
кто даст инфы, хочу сделать проверки в своей программе:
  • Открылся файл
  • Существует ли файл
  • Не равен ли файл 0 байт
  • Все файлы тхт
...что бы программа не останавливала работу а просто пропускала этот файл ( т.е начинала читать следующий файл) может кто то даст пример кода.
Ваша "program oshi;" ничего этого не делает.

Набор команд для работы с файлами:Assign, Reset, Rewrite, BlockRead, BlockWrite, Read, Readln, Write, WriteLn, Close, IOResult тянется ещё с древних времён для однозадачных ОС (ДОСа). В многозадачных (Linux, Windows, ...) файл может быть открыт несколькими программами одновременно. И пока вы будете читать, данные могут быть переписаны. Поэтому надо использовать команды работы с файлами с поддержкой прав доступа. Потоки данных TFileStream это поддерживают — "всем запретить запись, пока я читаю".

В вашем случае интенсивной работы нет и хватит обойтись без прав доступа.


Цитата:
А как вам такой вариант???
Код:
except                                                                                                                                                                
on E:Exception do                                                                                                                                                                                                                                                                                                                    
writeln('файла нет: ' ,E.Message);                                                                                                                                    
 end;                                                                                                                                                                       
end.
Наверное это лишнее, пока пользуйтесь IOResult.
jillitil вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Парни помогите плиз,очень надо zayai Паскаль, Turbo Pascal, PascalABC.NET 2 13.01.2009 20:39