|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
Операция с файлами через FileStream
Здравствуйте господа.
Поиском пользовался, не нашел, Delphi выбрал по принадлежности к Паскалю. Прошу не пинать, отнестись с пониманием. Задача такая, выбираем файл на диске (bin), определяем участок файла для исследования двумя значениями "Старт Адрес" и "Стоп Адрес", начало области не обязательно должно совпадать с началом файла и вводим еще одно контрольное значение (в моем случае это контрольная сумма). Программа подсчитывает К.С. обозначенного участка, сравнивает с контрольным значением, если совпадения нет, то "Старт Адрес" увеличиваем на один и так далее. Вот набросок: Код:
procedure TForm1.Button1Click(Sender: TObject); // выбор файла begin If OpenDialog1.Execute then LabeledEdit1.Text:=Opendialog1.FileName; end; procedure TForm1.Button2Click(Sender: TObject); // обработка var Siz, CRC: Cardinal; FSize: Int64; begin FSize:=HexToInt(LabeledEdit3.Text); ??????????????????????????????????? // загрузить файл CRC:=FileCRC(LabeledEdit1.Text); LabeledEdit4.Text:=IntToHex(CRC,8); end; //---------------------------------------------- lmikle: Пользуемся тегами! (вначале хочу научиться загружать и выделять участок файла, а потом и дальше можно) Почитав и подумав решил работать с выбранным файлом через FileStream ибо там проще и обозначить "Старт Адрес" - смещение и "Стоп Адрес" как размер ("Стоп Адрес" минус "Старт Адрес"), но вот опыта нет для загрузки выбранного файла в поток. Если у вас есть идеи ли в моем выборе есть ошибка, прошу подсказать. Если есть ссылка на пример похожий на мою задачу (основная загвоздка в загрузке файла и выделение участка файла), буду весьма признателен. Извините если мой вопрос несуразен или примитивен. |
#2
|
|||
|
|||
что-то типа такого:
Код:
var AStream : TFileStream; AData : Pointer; ADataLength : Integer; begin GetMem(AData,ADataLength); // Забираем кусок файла в память AStream := TFileStream.Create('Здесь имя файла',fmOpenRead); AStream.Seek(1024,soFromBegining); AStream.ReadBlock(AData,ADataLength); AStream.Free; // Здесь считаем CRC ... // Освобождаем память FreeMem(AData,ADataLength); end; |
#3
|
|||
|
|||
Спасибо уважаемый lmikle, принцип понял.
За правку сообщения благодарю, исправлюсь. |
#4
|
|||
|
|||
Долго не спрашивал, просто пытался сам, но...
Последний раз редактировалось LIC, 24.07.2009 в 23:22. |
#5
|
|||
|
|||
Доброе время суток.
Благодаря подсказке уважаемого lmikle освоил и реализовал FileStream поток, смог решить свою задачу, но вот возникла новая проблема. После открытия исследуемого файла пр-рой OpenDialog создаем новый файл при помощи FileStream нужного размера и проверяем CRC, если есть не равенство с искомым, то создаем новый файл с размером меньше на один байт и так по кругу. Но после определенного круга Windows выдает ошибку, что не может найти исходный файл, в чем проблема, может кто сталкивался. Код:
function TForm1.FileCRC32(const FileName: string): Cardinal; var InFile, Stream1, Stream2 : TFileStream; crc32: Int64; Res: Int64; BufPtr: Pointer; Sz, Ps: Integer; S1, S2: Int64; begin Ps:= StrToInt('$'+LabeledEdit2.Text); BufPtr := @Buf; crc32 := $FFFFFFFF; try //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Stream1 := TFileStream.Create(OpenDialog1.FileName, fmOpenRead); Stream1.Seek(Ps, soBeginning); Stream2 := TFileStream.Create('Temp.tmp', fmCreate, fmOpenWrite); Stream2.Seek(0, soBeginning); Sz := Stream1.Size ; Sz:= Sz-Ps; Stream2.CopyFrom(Stream1, Sz); finally Stream2.Free; Stream1.Free; end; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ try InFile := TFileStream.Create('Temp.tmp', fmOpenRead); InFile.Seek(0, soBeginning); Res := InFile.Read(Buf, BufLen); while (Res <> 0) do begin crc32 := UpdateCrc32(crc32, BufPtr, Res); Res := InFile.Read(Buf, BufLen); end; InFile.Destroy; except on E: Exception do begin if Assigned(InFile) then InFile.Free; ShowMessage(Format('При обработке файла [%s] произошла ' + 'ошибка [%s]', [FileName, E.Message])); end; end; Result:= crc32; //XOR Out not = FFFFFFFF LabeledEdit4.Text:=IntToHex(CRC32,8); begin DeleteFile('Temp.tmp'); Inc(Ps); LabeledEdit2.Text:=IntToHex(Ps,8); S1:= StrToInt('$'+ LabeledEdit3.Text); S2:= CRC32; if Pointer(S1) = Pointer(S2) then begin Ps:= StrToInt('$'+LabeledEdit2.Text); LabeledEdit2.Text:=IntToHex(Ps,8); end Это один из вариантов, пробовал разные варианты. Где моя ошибка? Подскажите пожалуйста. |
#6
|
|||
|
|||
Навскидку:
1. Stream2 := TFileStream.Create('Temp.tmp', fmCreate, fmOpenWrite); -> Stream2 := TFileStream.Create('Temp.tmp', fmCreate); 2. InFile.Destroy; -> InFile.Free; 3. Вообще, у тебя что-то мудренно все делается. Во первых, можно не создавать файл, а использовать поток в памяти - TMemoryStream. И во вторых - незачем переписывать файл кучу раз, найди готовый алгоритм расчета crc32, который будет нормально работать с потоками. |
#7
|
|||
|
|||
Ну мудрено получилось, так это от не знания языка, когда знаешь, то получается коротко и красиво, а вот алгоритм CRC32 пришлось писать самому, ну не в корне, а по мелочам. Да и ошибка у меня не с вновь созданным файлом (Temp.tmp), а именно с файлом исходником,
OpenDialog1.FileName. Спасибо, извините если описываю сумбурно. |