На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS

Дорогие друзья! Поздравляем вас с Новым 2025 годом!

Всем удачи, успеха и благополучия!

msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
... (продолжение следует) ...

Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...
Модераторы: jack128, D[u]fa, Shaggy, Rouse_
  
> "Stream read error" , От чего бы это?
    Привет всем!
    Пишу программу для поиска дублей на диске.
    В ф-ции, приведенной ниже, вылетет ошибка на вызове другой ф-ции.
    Ошибка "Stream read error", причем вылетает не срузу, первый раз где-то на 10 вызове(примерно), во второй на 36-ом, а в 3-й - на 24-ом.
    От чего это может быть и как такое лечится?
    Заренее благодарю.
    ExpandedWrap disabled
      type
       
      TFileRecord=record
      FileName:string[255];
      Size:integer
      end;
       
      TFileRecordHash=record
      FileName:string[255];
      Size:integer;
      Hash:string[16];
      end;
       
      var
      FileTable:array of TFileRecord;
      FileTableHash:array of TFileRecordHash;  //пока не используется
      Duplicates:array of array of TFileRecord;
      RemoveList:array of char;
      Canceled:boolean;
       
      ........................
       
      procedure FindDuplicates;
      var
      i,j:integer;
      ItemClosed:boolean;
       
      //////////////////////////////////
      ////Побйтно сравнивает два файла//
      //////////////////////////////////
      function CompFiles(Name1,Name2:string):boolean;
      var
      i:integer;
      Buf1,Buf2:byte;
      f1,f2:TFileStream;
      begin
      try
      f1:=TFileStream.Create(Name1,fmOpenRead);
      f2:=TFileStream.Create(Name2,fmOpenRead);
      for i:=0 to f1.Size do
        begin
          f1.ReadBuffer(Buf1,1);
          f2.ReadBuffer(Buf2,1);
          if Buf1<>Buf2 then
            begin
              result:=false;
              exit
            end
        end;
      result:=true;
      finally
      f1.Free;
      f2.Free;
      end
      end;
       
      begin
      try
      for i:=0 to Length(FileTable)-1 do
        if Length(FileTable[i].FileName)<>0 then
          begin
            ItemClosed:=true;
            for j:=0 to Length(FileTable)-1 do
              if Length(FileTable[j].FileName)<>0 then
                if i<>j then
                  if FileTable[i].Size=FileTable[j].Size then
                    if CompFiles(FileTable[i].FileName,FileTable[j].FileName) then  //Здесь ошибка
                      begin
                        if ItemClosed then
                          begin
                            SetLength(Duplicates,Length(Duplicates)+1);
                            SetLength(Duplicates[Length(Duplicates)-1],{Length(Duplicates[Length(Duplicates)-1])|+}1);
                            Duplicates[Length(Duplicates)-1,0]:=FileTable[i];
                            ItemClosed:=false
                          end;
                        SetLength(Duplicates[Length(Duplicates)-1],Length(Duplicates[Length(Duplicates)-1])+1);
                        Duplicates[Length(Duplicates)-1,Length(Duplicates[Length(Duplicates)-1])-1]:=FileTable[j];
                        SetLength(FileTable[j].FileName,0)
                      end;
            SetLength(FileTable[i].FileName,0)
          end;
      finally
      SetLength(FileTable,0)
      end
      end;
    Сообщение отредактировано: Alexander N -
      возможно не совпадают размеры файлов. и если уж в цикле от 0, то, имхо до Size-1.
      так же возможно имеет смысл использовать не ReadBuffer, а Read, и проверять, что он возвращает корректно прочитанный размер. либо ловить и обрабатывать исключение с пом try..except
        Цитата Alexander N @
        ExpandedWrap disabled
          for i:=0 to f1.Size do
            begin
              f1.ReadBuffer(Buf1,1);
              f2.ReadBuffer(Buf2,1);
              if Buf1<>Buf2 then
                begin
                  result:=false;
                  exit
                end
            end;

        ExpandedWrap disabled
          if f1.Size = f2.Size then
          begin
          for i:=0 to f1.Size - 1 do
            begin
              f1.ReadBuffer(Buf1,1);
              f2.ReadBuffer(Buf2,1);
              if Buf1<>Buf2 then
              begin
                result:=false;
                exit
              end
            end;
          end else
            result := false;
          Мда-а-а, читать файлы по 1 байту это супер :wacko:
          ExpandedWrap disabled
            function CompFiles(const Name1,Name2:string):boolean;
            var
              FSize,BSize:integer;
              Buf1,Buf2:array[0..4095] of char;
              f1,f2:TFileStream;
            begin
              Result:=false;
              f1:=TFileStream.Create(Name1,fmOpenRead);
              f2:=nil;
              try
                f2:=TFileStream.Create(Name2,fmOpenRead);
                FSize:=f1.Size;
                if f2.Size <> FSize then Exit; //!!! проверяем равенство размера
                repeat
                  BSize:=FSize;
                  if BSize > SizeOf(Buf1) then BSize:=SizeOf(Buf1);
                  f1.ReadBuffer(Buf1,BSize);
                  f2.ReadBuffer(Buf2,BSize);
                  if not CompareMem(Buf1,Buf2,BSize) then Exit;
                  dec(FSize,BSize);
                until FSize <= 0;
                Result:=true;
              finally
                f1.Free;
                f2.Free;
              end;
            end;


          Добавлено
          Да и циклы по FileTable ужасно сделаны - нафига гонять второй цикл от 0, когда достаточно от i+1 ?! И куча вложенных if-ов никчему, т.к. можно все в одну строчку написать
          ExpandedWrap disabled
            for i:=0 to Length(FileTable)-1 do
              if FileTable[i].FileName <> '' then
              begin
                ItemClosed:=true;
                for j:=i+1 to Length(FileTable)-1 do
                  if (FileTable[j].FileName <> '') and (FileTable[i].Size = FileTable[j].Size) and
                     CompFiles(FileTable[i].FileName,FileTable[j].FileName) then
                  begin
                     ...
                  end;
              end;
          Сообщение отредактировано: leo -
            Цитата leo @
            RSize:=0;

            Вроде в объявлении переменных таковой нет.leo, что вы имели в виду?
              Цитата Alexander N @
              Вроде в объявлении переменных таковой нет.leo, что вы имели в виду?

              Эх, на 3 сек. не успел исправить - это не нужно, от другого варианта затесалось...
                Цитата leo @
                FSize:=f1.Size;
                if f2.Size <> FSize then Exit; //!!! проверяем равенство размера

                А разве нельзя
                ExpandedWrap disabled
                  if f1.Size<>f2.Size
                ?

                И вложенные условия нужны для того, чтобы если первое услови не выполняется, не вычислять последующие, т. к. прога должна работать быстро.
                Сообщение отредактировано: Alexander N -
                  Цитата Alexander N @
                  А разве нельзя
                  if f1.Size<>f2.Size

                  Можно, только это "не оптимально" ;), т.к. при при чтении св-ва f1.Size вызывается ф-я АПИ GetFileSize - меня от этих излишеств "коробит" :)

                  Добавлено
                  Цитата Alexander N @
                  И вложенные условия нужны для того, чтобы если первое услови не выполняется, не вычислять последующие, т. к. прога должна работать быстро

                  В дельфи и так по умолчанию стоит опция сокращенного вычисления булевских выражений (галка Compleate boolean eval выключена), поэтому как только в цепочке AND встречается false - дальнейшие вычисления прекращаются
                    Цитата leo @
                    галка Compleate boolean eval выключена
                    Оффтопик, но где эту галку искать. например в d7?

                    Добавлено
                    MetalFan, спасибо, с Вашим исправлением прогнал прогу по диску, она больше не слетает(пока ;) ).
                    Цитата Profi @
                    if f1.Size = f2.Size then
                    begin
                    for i:=0 to f1.Size - 1 do
                    begin
                    f1.ReadBuffer(Buf1,1);
                    f2.ReadBuffer(Buf2,1);
                    if Buf1<>Buf2 then
                    begin
                    result:=false;
                    exit
                    end
                    end;
                    end else
                    result := false;

                    Profi, зчем сравнивать файлы по размеру, если это уже делается до вызова ф-ции, и совпаадение размеров - условие вызова это ф-ции?
                    leo, спасибо за ф-цию сравнения, пока не успел попробовать
                      Цитата Alexander N @
                      Оффтопик, но где эту галку искать. например в d7?

                      Project -> Options -> Compiler -> SyntaxOptions -> Complete boolean eval - по умолчанию выключена, т.е. булевские выражения считаются не полностью, а слево-направо пока не станет ясен результат
                        Спасибо!
                          Alexander N, просто не смотрел реализацию второй функции.
                          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                          0 пользователей:


                          Рейтинг@Mail.ru
                          [ Script execution time: 0,0391 ]   [ 16 queries used ]   [ Generated: 15.01.25, 11:55 GMT ]