Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Запись списка в файл


Автор: VanHelsing 23.7.2009, 11:38
Суть такова. Заполняется список, записывается в файл. При следующем открытии программы необходимо считать информацию из файла, записать в список и сравнить списки. Работу с файлами выполнить с помощью WinAPI.
Заполняю стуктуру:
Код

procedure TMainForm.FormCreate(Sender: TObject);
var
  i:integer;
begin
  HFile:=CreateFile('test.log',GENERIC_WRITE {and GENERIC_READ},FILE_SHARE_READ,
                      nil,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
  {*Создаем файл TEST.TXT, получаем доступ к записи,
     другим процессам разрешается читать файл, файл создается перезаписыванием,
     назначаем стандартный дескриптор безопасности  *}
  if (GetLastError()=INVALID_HANDLE_VALUE) then
     ShowMessage('Не удалось создать файл');
  IndexList:=0;
  MyList:=TStringList.Create;
  MyListRead:=TStringList.Create;
  for I := 0 to 3 do
    begin
      mList.Lines.Add(btnCreateFile.Caption);
      mList.Lines.Add(btnFileWrite.Caption);
      MyList.Add(mList.Lines.Strings[i]);
    end;
  mList.Clear;
end;


Записываю в файл:
Код

procedure TMainForm.btnFileWriteClick(Sender: TObject);
var
  i:integer;
begin
  for i := 0 to MyList.Count - 1 do
   begin
    str:=MyList.Strings[i];
    WriteFile(HFile,str,Length(str),NumberWrite,nil);
    {запись в файл}
    inc(IndexList);
   end;
    FileClose(HFile);
end;

А вот со чтением проблема - надо знать количество записанной информации, вот не знаю как это сделать.  

Автор: Yanis 23.7.2009, 11:46
Ну и обратись в раздел http://forum.vingrad.ru/index.php?show_type=forum&showforum=85, а не в общие вопросы. Ты ж не первый день на форуме, а как маленький, ей богу.

Автор: Riply 23.7.2009, 12:07
Цитата(VanHelsing @  23.7.2009,  11:38 Найти цитируемый пост)
А вот со чтением проблема - надо знать количество записанной информации, вот не знаю как это сделать


А что мешает сначала писать размер, потом данные ?
Т.е. структурами такого типа:
type
 MY_SIZED_DATA = packed record
   DataLength: ULONG;
   Data: array[0..0] of BYTE;
 end;

Автор: CodeMonkey 23.7.2009, 12:27
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1206#06
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=169

Автор: VanHelsing 23.7.2009, 19:46
Yanis извини забыл - исправлюсь. smile 
Riply да такой вариант возможен, но получается что данную структуру надо тоже писать в файл.
CodeMonkey видимо я невнимательно читал, но ничего подходящего мне не нашел.
P.S. модераторы перенесите пожалуйста тему.

Автор: CodeMonkey 23.7.2009, 19:53
Цитата(VanHelsing @  23.7.2009,  19:46 Найти цитируемый пост)
видимо я невнимательно читал, но ничего подходящего мне не нашел

Мда.... http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1206#06 - 1-к-1 ваше. Только слово "запись" выкиньте при чтении.

Автор: VanHelsing 24.7.2009, 10:11
CodeMonkey спасибо большое. Через TFileStream я сделал - это не сложно.
Но хотелось бы сделать это через ReadFile. Честно очень стыдно, но я не совсем понимаю почему не могу использовать в качестве принимающего буфера переменную типа TStringList. И хотелось бы знать что я могу использовать в качестве буфера(кроме переменной типа String)?

Автор: niteo 24.7.2009, 10:25
Цитата(VanHelsing @  24.7.2009,  10:11 Найти цитируемый пост)
 почему не могу использовать в качестве принимающего буфера переменную типа TStringList

Это класс.
Цитата(VanHelsing @  24.7.2009,  10:11 Найти цитируемый пост)
я могу использовать в качестве буфера

Все что хошь smile

Используй TPersistent

Автор: CodeMonkey 24.7.2009, 11:20
Цитата(VanHelsing @  24.7.2009,  10:11 Найти цитируемый пост)
Через TFileStream я сделал - это не сложно. Но хотелось бы сделать это через ReadFile.

...если учесть, что TFileStream - это обёртка над ReadFile, то, что и говорить, задача эта сложная и неразрешимая smile 

Цитата(VanHelsing @  24.7.2009,  10:11 Найти цитируемый пост)
 Честно очень стыдно, но я не совсем понимаю почему не могу использовать в качестве принимающего буфера переменную типа TStringList.

Наверное потому, что вы не используете её в качестве источника. В файл вы пишите набор String-ов. TStringList в этом действе не участвует.
Я не знаю, вам может MyList.SaveToFile/MyList.LoadFromFile подойдёт? 

Автор: VanHelsing 24.7.2009, 18:48
Все большое спасибо. Вроде бы получилось.
Заполнение записи:
Код

var
  MainForm: TMainForm;//главная форма
  HFile:THandle;//дескриптор файла
  MyList,MyListRead:TStringList;
  NumberWrite,NumberRead,sizeWrite:Cardinal;
  str:WideString;
  IndexList:integer;

procedure TMainForm.FormCreate(Sender: TObject);
var
  i:integer;
begin
  IndexList:=0;
  MyList:=TStringList.Create;
  MyListRead:=TStringList.Create;
  for I := 0 to 3 do
    begin
      mList.Lines.Add(btnCreateFile.Caption);
      mList.Lines.Add(btnFileWrite.Caption);
      //MyList.Add(IntToStr(Length(mList.Lines.Strings[i])));
      MyList.Add(mList.Lines.Strings[i]);
    end;
  mList.Clear;
end;
HFile:=CreateFile('test.log',GENERIC_WRITE {and GENERIC_READ},FILE_SHARE_READ,
                      nil,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);  
  if (GetLastError()=INVALID_HANDLE_VALUE) then
     ShowMessage('Не удалось создать файл')
  else
    begin
     btnFileWrite.Enabled:=true;
     btnFileRead.Enabled:=true;
    end;

Запись в файл:
Код

procedure TMainForm.btnFileWriteClick(Sender: TObject);
{Запись файла}
var
  i:integer;
  strCount:Integer;
begin
   for I := 0 to MyList.Count- 1 do
    begin
      strCount:=Length(MyList.Strings[i]);
      {Запись в файл размера строки}
      WriteFile(HFile,strCount,SizeOf(Integer),NumberWrite,nil);
      {запись в файл строки списка}
      str:=MyList.Strings[i];
      WriteFile(HFile,str,Length(MyList.Strings[i]),NumberWrite,nil);
    end;
    FileClose(HFile);
end;

Чтение из файла:
Код

procedure TMainForm.btnFileReadClick(Sender: TObject);
var
  i:integer;
  //strCount:Cardinal;
  strCount:Integer;
begin
  HFile:=CreateFile('test.log',GENERIC_READ,FILE_SHARE_READ,
                      nil,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);  
  if HFile=0 then
   begin
     ShowMessage('Файл не существеут');
     Exit;
   end;
   for I := 0 to MyList.Count- 1 do
    begin
       ReadFile(HFile,strCount,SizeOf(Integer),NumberRead,nil);
       ReadFile(HFile,str,strCount,NumberRead,nil);
       MyListRead.Add(str);
    end;
end;

P.S. если где не прав, то обязательно подскажите. smile 

Автор: CodeMonkey 25.7.2009, 09:39
Неправы. http://www.delphikingdom.ru/quintana/quintana.asp?ItemID=10#no11.

P.S. Кстати, а какой у вас смысл писать в файл unicode-строку? Это внешнее требование?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)