![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Работа с текстовым файлом [D6, D7, Win2k, WinXP]
Агат © (2005-08-23 23:47:00)1) Как файл *.111 (...к примеру. Зная, что он легко открывается блокнотом) открыть в виде текстового файла?
2) Как в открытом файле выцепить только определённые строки? Скажем, строку №3, 5, 7... и т.д. Эти строки несут в себе информацию о местонахождении некоего файла.
3) Получив полный путь этих файлов, необходимо поместить все эти файлы в определённую папку.
В голове крутится решение этой задачи, но никак не могу понять с чего начать. Подскажите хотябы "скелет" программы.
Anatoly Podgoretsky (2005-08-30 15:18:00) [1]Агат (30.08.05 14:32) [10]
В твоем коде не видать игнорирования строк, если ты хочешь делать это таким путем, то ты должен из удалить от туда, после загрузки.
Агат (2005-08-30 14:32:00) [2]Можете подсказать, в правильном направлении вообще я двигаюсь? Или чего не так?
Вот что я накидал:
=========================================
unit m3u_2_folder;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ShellAPI, ShlObj, ExtCtrls;
type
TForm1 = class(TForm)
OpenDialog1: TOpenDialog;
SaveDialog1: TSaveDialog;
Button1: TButton;
Button2: TButton;
Label1: TLabel;
Label2: TLabel;
Button4: TButton;
Button3: TButton;
Label3: TLabel;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Otkuda, Kuda: boolean;
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
//Открытие диалогового окна "Открыть"
if OpenDialog1.Execute then
begin
//Делаем так, чтобы было видно, какой файл выбрали
label1.Caption := 'Путь: ' + LowerCase(OpenDialog1.FileName);
Otkuda:= true;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
TitleName : string;
lpItemID : PItemIDList;
BrowseInfo : TBrowseInfo;
DisplayName : array[0..MAX_PATH] of char;
TempPath : array[0..MAX_PATH] of char;
begin
//Вызов диалогового окна "Обзор папок"
FillChar(BrowseInfo, sizeof(TBrowseInfo), #0);
BrowseInfo.hwndOwner := Form1.Handle;
BrowseInfo.pszDisplayName := @DisplayName;
TitleName := 'Выберите директорию:';
BrowseInfo.lpszTitle := PChar(TitleName);
BrowseInfo.ulFlags := BIF_RETURNONLYFSDIRS;
lpItemID := SHBrowseForFolder(BrowseInfo);
if lpItemId <> nil then
begin
SHGetPathFromIDList(lpItemID, TempPath);
GlobalFreePtr(lpItemID);
//Делаем так, чтобы было видно, в какую папку копируем
Label2.Caption := 'Путь: ' + TempPath;
Kuda:= true;
end;
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
Close;
end;
procedure TForm1.Button3Click(Sender: TObject);
var
List:TStrings; //Переменная списка строк типа TStringList
begin
//Проверка на наличие выбора файла и каталога
If Otkuda <> true then
MessageDlg('Выберите файл Плей-листа. Нажмите кнопку "Откуда".',mtInformation,[mbOk],0) else
If Kuda <> true then
MessageDlg('Укажите каталог для сохранения. Нажмите кнопку "Куда".',mtInformation,[mbOk],0) else
Begin
List:= TStringList.Create(); //Размещаем переменную в памяти
List.LoadFromFile(LowerCase(OpenDialog1.FileName));// Загружаем текстовый файл
Label3.Caption := 'Число строк в файле: ' + (inttostr (List.Count)); //Отображение кол-ва строк в файле
List.SaveToFile('01.txt');
List.Free;
End;
end;
end.
=========================================
Anatoly Podgoretsky (2005-08-28 20:38:00) [3]if S[1] <> '*' then ...
Агат (2005-08-28 18:23:00) [4]Подскажите, как в текстовом файле игнорировать строки, начинающиеся с символа "*"?
Джо (2005-08-26 21:30:00) [5]Класс в [3] спроектирован наспех, если не сказать большего. Поэтому есть недочеты. В частности, исправлю тут возможность утечки памяти в конструкторе. Нужно так:
constructor TFileCopier.Create(AListFile: TFileName;
const MinLines: Integer; AForceDirCreation: Boolean = True);
begin
FList := TStringList.Create;
FList.LoadFromFile(AListFile);
if FList.Count < MinLines then
begin
FList.Free;
raise Exception.CreateFmt('Количество строк в файле меньше %d',[MinLines]);
end;
FForceDirCreation := AForceDirCreation
end;
Для того, чтобы не было так коряво, необходим пустяшный рефакторинг, ну да ладно ;-)
Zeqfreed (2005-08-26 21:03:00) [6]Агат (26.08.05 21:01) [5]
"Отдохните от рекламы"...
Агат (2005-08-26 21:01:00) [7]To: Anatoly Podgoretsky - :-)
To: Джо - Once again Thanks!!! Сейчас... пережую информацию :)
Толковый форум! Самое главное, безо всякой регистрации и рекламы! В закладки...
Anatoly Podgoretsky (2005-08-24 09:57:00) [8]Агат (23.08.05 23:47)
Очень хорошо, но зачем же сразу так много вопросов? Задавай их по одному и твои шансы повысятся.
Джо (2005-08-24 00:41:00) [9]Держи, как "скелет" пойдет.
Юнит с классом, инкапсулирующим все эти манипуляции:
unit FileCop;
interface
uses Windows, SysUtils, Classes, Dialogs;
type
TFileCopier = class
private
FList: TStrings;
FDestDir: TFileName;
FForceDirCreation: Boolean;
procedure SetDestDir(const Value: TFileName);
public
constructor Create (AListFile: TFileName;
const MinLines: Integer; AForceDirCreation: Boolean = True);
destructor Destroy; override;
procedure Copy (const LineNumbers: array of Integer);
property DestDir: TFileName read FDestDir write SetDestDir;
end;
implementation
{ TFileCopier }
procedure TFileCopier.Copy(const LineNumbers: array of Integer);
var
I: Integer;
FN: string;
begin
for I := Low(LineNumbers) to High(LineNumbers) do
begin
FN := FList[LineNumbers[I]];
if not CopyFile (
PChar(FN),
PChar(FDestDir+'\'+ExtractFileName(FN)),
False
) then RaiseLastOSError;
end;
end;
constructor TFileCopier.Create(AListFile: TFileName;
const MinLines: Integer; AForceDirCreation: Boolean = True);
begin
FList := TStringList.Create;
FList.LoadFromFile(AListFile);
if FList.Count < MinLines then
raise Exception.CreateFmt('Количество строк в файле меньше %d',[MinLines]);
FForceDirCreation := AForceDirCreation
end;
destructor TFileCopier.Destroy;
begin
FList.Free;
inherited;
end;
procedure TFileCopier.SetDestDir(const Value: TFileName);
begin
FDestDir := Value;
if FForceDirCreation and not DirectoryExists(FDestDir) then
ForceDirectories(FDestDir)
end;
end.
Названия параметров, методов и свойств говорят сами за себя, впрочем вот пример использования.
Форма, на ней кнопка, в обработчике нажатия код:
procedure TForm1.Button1Click(Sender: TObject);
var
Copier: TFileCopier;
begin
// указываем файл, в котором хранится список,
// минимальное кол-во строк в нем,
// а также указываем, чтобы директория назначения создавалась
// автоматически, если она не существует
Copier := TFileCopier.Create('d:\1.txt',6,True);
try
// указываем, в какую папку копировать
Copier.DestDir := 'd:\2';
// копируем файлы, имена которых находятся в строках 1,3 и 5.
// (нумерация - с 0)
Copier.Copy([1,3,5]);
finally
Copier.Free;
end;
end;
Образец файла со списком:
D:\bin\TASM50\BIN\THUNK.EXE
D:\bin\TASM50\BIN\TLIB.EXE
D:\bin\TASM50\BIN\TLINK.EXE
D:\bin\TASM50\BIN\TLINK32.EXE
D:\bin\TASM50\BIN\TOUCH.EXE
D:\bin\TASM50\BIN\WINSTUB.EXE
Разбирайся. Просмотри внутренности класса, чтобы понять как это делается. Удачи.
Агат (2005-08-24 00:28:00) [10]Thanks Джо!
Джо (2005-08-24 00:02:00) [11](1) и (2): открываешь как обычный паскалевский TextFile и читаешь построчно используя ReadLn. Ведешь счетчик прочитанных строк, нужные строки запоминаешь и делаешь с ними что хочешь. Вариант второй: используешь класс TStringList и его метод LoadFromFile. Затем обращаешься к конкретным строкам по их номеру AStrings[I]...
(3) - CopyFile