按文件名遍历文件夹及子文件夹查找文件并打开

时间:2023-01-25 12:29:29
设想:

纸质文件上有条码(条码是文件名),电脑上接条码扫描枪,当扫描抢扫过纸质文件上的条码后,

就按文件名遍历文件夹及子文件夹查找文件并打开该文件。

可以实现吗?这个要如何写?

12 个解决方案

#1


用FindFirst FindNext 来找文件

#2


为啥还要遍历??直接用fileexist不行吗??

#3


如果知道文件是保存在哪个目录当然就不需要遍历了,直接打开它

#4


引用 3 楼 sololie 的回复:
如果知道文件是保存在哪个目录当然就不需要遍历了,直接打开它


文件类别分的很细,有根目录,根目录下面有子目录。

#5


指定一个根目录,然后递归遍历就行了啊
也是用FindFirst、FindNext

#6


网上找的,麻烦那位仁兄帮我改改:
搜到我要的文件就直接打开

procedure TFileManager.FindFileList(Path: string);
var
sr:TSearchRec;
fr:Integer;
sFind:string;
begin
...
fr:=FindFirst(sFind,faAnyFile,sr);
while fr=0 do
  begin
  if(sr.Attr=faDirectory)and(sr.Name<>'.')and(sr.Name<>'..') then
    begin
    ...
    FindFileList(sr.Name);//循环调用
    end;
  fr:=FindNext(sr);
  end;
FindClose(sr);
end;

#7


我这个例子里面可以借鉴,稍微修改一下
http://download.csdn.net/detail/xstdljj/4410553

#9




uses ShellAPI;

// pathRoot:搜索的根目录
// tagFileName: 要找的文件名
// outPath: 搜索到的文件路径
procedure FindFile(pathRoot, tagFileName: string; var outPath: string);
var
  tagPath: string;
  ser: TSearchRec;
begin
  Application.ProcessMessages;
  tagPath := pathRoot;
  if FindFirst(tagPath + '*.*', faAnyFile, ser) = 0 then
  begin
    repeat
      // 先找文件
      if ((ser.name <> '.') and (ser.name <> '..')
        and ((SysUtils.FileGetAttr(tagPath + ser.name) and faDirectory) <>
        faDirectory)) then
      begin
        // 找到文件后用记事本打开
        if StrComp(@UpperCase(tagFileName)[1], @UpperCase(ser.Name)[1]) = 0 then
        begin
          outPath := tagPath + ser.Name;
          FindClose(ser);
          Exit; // 找到一个 tagFileName 文件就退出,忽略其他可能存在的同名文件
        end;
      end;
    until FindNext(ser) <> 0;

    // 然后递归找目录
    if FindFirst(tagPath + '*.*', faAnyFile, ser) = 0 then
    begin
      repeat
        if ((ser.name <> '.') and (ser.name <> '..')
          and ((SysUtils.FileGetAttr(tagPath + ser.name) and faDirectory) =
          faDirectory)) then
        begin
          FindFile(tagPath + ser.name + '\', tagFileName, outPath);
        end;
      until FindNext(ser) <> 0;
    end;
  end;

  FindClose(ser);
end;

// 调用示例
procedure TForm1.btn1Click(Sender: TObject);
var
  pathRoot, tagFileName, tagPath: string;
begin
  pathRoot := 'c:\'; // 要遍历的目录,尽量指定最小范围的跟路径
  tagFileName := 'test.txt'; // 要找的文件名,不包含路径
  tagPath := ''; // 搜索到的文件路径

  ShowMessage('确定后开始搜索文件: ' + tagFileName);
  FindFile(pathRoot, tagFileName, tagPath);

  if tagPath <> '' then
  begin
    // 用记事本打开找到的文件
    ShellExecute(0, 'open', 'notepad.exe', PChar(tagPath),
      nil, SW_SHOWNORMAL);
  end
  else
    ShowMessage('没有找到文件: ' + tagFileName);
end;

#10


把上面的改一下,不然内存很快就爆了


uses ShellAPI;

// pathRoot:搜索的根目录
// tagFileName: 要找的文件名
// outPath: 搜索到的文件路径
procedure FindFile(pathRoot, tagFileName: string; var outPath: string);
var
  ser: TSearchRec;
begin
  Application.ProcessMessages;
  if FindFirst(pathRoot + '*.*', faAnyFile, ser) = 0 then
  begin
    repeat
      // 先找文件
      if ((ser.name <> '.') and (ser.name <> '..')
        and ((SysUtils.FileGetAttr(pathRoot + ser.name) and faDirectory) <>
        faDirectory)) then
      begin
        // 找到文件后用记事本打开
        if StrComp(@UpperCase(tagFileName)[1], @UpperCase(ser.Name)[1]) = 0 then
        begin
          outPath := pathRoot + ser.Name;
          FindClose(ser);
        end;
      end;
    until FindNext(ser) <> 0;
    FindClose(ser);
  end;

  // 然后递归找目录
  if FindFirst(pathRoot + '*.*', faAnyFile, ser) = 0 then
  begin
    repeat
      if ((ser.name <> '.') and (ser.name <> '..')
        and ((SysUtils.FileGetAttr(pathRoot + ser.name) and faDirectory) =
        faDirectory)) then
      begin
        FindFile(pathRoot + ser.name + '\', tagFileName, outPath);
      end;
    until FindNext(ser) <> 0;
    FindClose(ser);
  end;
end;


调用还是一样

#11


引用 10 楼 sololie 的回复:
把上面的改一下,不然内存很快就爆了


uses ShellAPI;

// pathRoot:搜索的根目录
// tagFileName: 要找的文件名
// outPath: 搜索到的文件路径
procedure FindFile(pathRoot, tagFileName: string; var outPath: string);
var
  ser: TSearchRec;
begin
  Application.ProcessMessages;
  if FindFirst(pathRoot + '*.*', faAnyFile, ser) = 0 then
  begin
    repeat
      // 先找文件
      if ((ser.name <> '.') and (ser.name <> '..')
        and ((SysUtils.FileGetAttr(pathRoot + ser.name) and faDirectory) <>
        faDirectory)) then
      begin
        // 找到文件后用记事本打开
        if StrComp(@UpperCase(tagFileName)[1], @UpperCase(ser.Name)[1]) = 0 then
        begin
          outPath := pathRoot + ser.Name;
          FindClose(ser);
        end;
      end;
    until FindNext(ser) <> 0;
    FindClose(ser);
  end;

  // 然后递归找目录
  if FindFirst(pathRoot + '*.*', faAnyFile, ser) = 0 then
  begin
    repeat
      if ((ser.name <> '.') and (ser.name <> '..')
        and ((SysUtils.FileGetAttr(pathRoot + ser.name) and faDirectory) =
        faDirectory)) then
      begin
        FindFile(pathRoot + ser.name + '\', tagFileName, outPath);
      end;
    until FindNext(ser) <> 0;
    FindClose(ser);
  end;
end;


调用还是一样

编译出错:StrComp(@UpperCase(tagFileName)[1], @UpperCase(ser.Name)[1])

#12


引用 11 楼 kckcxy 的回复:
编译出错:StrComp(@UpperCase(tagFileName)[1], @UpperCase(ser.Name)[1])


我在d7下编译通过,在其他版本上编译应该也不会有问题
这行代码的作用就是把比较的两端都转成大写,这样比较就能保证忽略英文大小写,
例如tagFileName是 AbcD.TXT , ser.Name 是 abcd.txt ,本身就是同一个文件,只不过大小写不同,
所以把它们统一转成大写(或小写)来进行比较。

#1


用FindFirst FindNext 来找文件

#2


为啥还要遍历??直接用fileexist不行吗??

#3


如果知道文件是保存在哪个目录当然就不需要遍历了,直接打开它

#4


引用 3 楼 sololie 的回复:
如果知道文件是保存在哪个目录当然就不需要遍历了,直接打开它


文件类别分的很细,有根目录,根目录下面有子目录。

#5


指定一个根目录,然后递归遍历就行了啊
也是用FindFirst、FindNext

#6


网上找的,麻烦那位仁兄帮我改改:
搜到我要的文件就直接打开

procedure TFileManager.FindFileList(Path: string);
var
sr:TSearchRec;
fr:Integer;
sFind:string;
begin
...
fr:=FindFirst(sFind,faAnyFile,sr);
while fr=0 do
  begin
  if(sr.Attr=faDirectory)and(sr.Name<>'.')and(sr.Name<>'..') then
    begin
    ...
    FindFileList(sr.Name);//循环调用
    end;
  fr:=FindNext(sr);
  end;
FindClose(sr);
end;

#7


我这个例子里面可以借鉴,稍微修改一下
http://download.csdn.net/detail/xstdljj/4410553

#8


#9




uses ShellAPI;

// pathRoot:搜索的根目录
// tagFileName: 要找的文件名
// outPath: 搜索到的文件路径
procedure FindFile(pathRoot, tagFileName: string; var outPath: string);
var
  tagPath: string;
  ser: TSearchRec;
begin
  Application.ProcessMessages;
  tagPath := pathRoot;
  if FindFirst(tagPath + '*.*', faAnyFile, ser) = 0 then
  begin
    repeat
      // 先找文件
      if ((ser.name <> '.') and (ser.name <> '..')
        and ((SysUtils.FileGetAttr(tagPath + ser.name) and faDirectory) <>
        faDirectory)) then
      begin
        // 找到文件后用记事本打开
        if StrComp(@UpperCase(tagFileName)[1], @UpperCase(ser.Name)[1]) = 0 then
        begin
          outPath := tagPath + ser.Name;
          FindClose(ser);
          Exit; // 找到一个 tagFileName 文件就退出,忽略其他可能存在的同名文件
        end;
      end;
    until FindNext(ser) <> 0;

    // 然后递归找目录
    if FindFirst(tagPath + '*.*', faAnyFile, ser) = 0 then
    begin
      repeat
        if ((ser.name <> '.') and (ser.name <> '..')
          and ((SysUtils.FileGetAttr(tagPath + ser.name) and faDirectory) =
          faDirectory)) then
        begin
          FindFile(tagPath + ser.name + '\', tagFileName, outPath);
        end;
      until FindNext(ser) <> 0;
    end;
  end;

  FindClose(ser);
end;

// 调用示例
procedure TForm1.btn1Click(Sender: TObject);
var
  pathRoot, tagFileName, tagPath: string;
begin
  pathRoot := 'c:\'; // 要遍历的目录,尽量指定最小范围的跟路径
  tagFileName := 'test.txt'; // 要找的文件名,不包含路径
  tagPath := ''; // 搜索到的文件路径

  ShowMessage('确定后开始搜索文件: ' + tagFileName);
  FindFile(pathRoot, tagFileName, tagPath);

  if tagPath <> '' then
  begin
    // 用记事本打开找到的文件
    ShellExecute(0, 'open', 'notepad.exe', PChar(tagPath),
      nil, SW_SHOWNORMAL);
  end
  else
    ShowMessage('没有找到文件: ' + tagFileName);
end;

#10


把上面的改一下,不然内存很快就爆了


uses ShellAPI;

// pathRoot:搜索的根目录
// tagFileName: 要找的文件名
// outPath: 搜索到的文件路径
procedure FindFile(pathRoot, tagFileName: string; var outPath: string);
var
  ser: TSearchRec;
begin
  Application.ProcessMessages;
  if FindFirst(pathRoot + '*.*', faAnyFile, ser) = 0 then
  begin
    repeat
      // 先找文件
      if ((ser.name <> '.') and (ser.name <> '..')
        and ((SysUtils.FileGetAttr(pathRoot + ser.name) and faDirectory) <>
        faDirectory)) then
      begin
        // 找到文件后用记事本打开
        if StrComp(@UpperCase(tagFileName)[1], @UpperCase(ser.Name)[1]) = 0 then
        begin
          outPath := pathRoot + ser.Name;
          FindClose(ser);
        end;
      end;
    until FindNext(ser) <> 0;
    FindClose(ser);
  end;

  // 然后递归找目录
  if FindFirst(pathRoot + '*.*', faAnyFile, ser) = 0 then
  begin
    repeat
      if ((ser.name <> '.') and (ser.name <> '..')
        and ((SysUtils.FileGetAttr(pathRoot + ser.name) and faDirectory) =
        faDirectory)) then
      begin
        FindFile(pathRoot + ser.name + '\', tagFileName, outPath);
      end;
    until FindNext(ser) <> 0;
    FindClose(ser);
  end;
end;


调用还是一样

#11


引用 10 楼 sololie 的回复:
把上面的改一下,不然内存很快就爆了


uses ShellAPI;

// pathRoot:搜索的根目录
// tagFileName: 要找的文件名
// outPath: 搜索到的文件路径
procedure FindFile(pathRoot, tagFileName: string; var outPath: string);
var
  ser: TSearchRec;
begin
  Application.ProcessMessages;
  if FindFirst(pathRoot + '*.*', faAnyFile, ser) = 0 then
  begin
    repeat
      // 先找文件
      if ((ser.name <> '.') and (ser.name <> '..')
        and ((SysUtils.FileGetAttr(pathRoot + ser.name) and faDirectory) <>
        faDirectory)) then
      begin
        // 找到文件后用记事本打开
        if StrComp(@UpperCase(tagFileName)[1], @UpperCase(ser.Name)[1]) = 0 then
        begin
          outPath := pathRoot + ser.Name;
          FindClose(ser);
        end;
      end;
    until FindNext(ser) <> 0;
    FindClose(ser);
  end;

  // 然后递归找目录
  if FindFirst(pathRoot + '*.*', faAnyFile, ser) = 0 then
  begin
    repeat
      if ((ser.name <> '.') and (ser.name <> '..')
        and ((SysUtils.FileGetAttr(pathRoot + ser.name) and faDirectory) =
        faDirectory)) then
      begin
        FindFile(pathRoot + ser.name + '\', tagFileName, outPath);
      end;
    until FindNext(ser) <> 0;
    FindClose(ser);
  end;
end;


调用还是一样

编译出错:StrComp(@UpperCase(tagFileName)[1], @UpperCase(ser.Name)[1])

#12


引用 11 楼 kckcxy 的回复:
编译出错:StrComp(@UpperCase(tagFileName)[1], @UpperCase(ser.Name)[1])


我在d7下编译通过,在其他版本上编译应该也不会有问题
这行代码的作用就是把比较的两端都转成大写,这样比较就能保证忽略英文大小写,
例如tagFileName是 AbcD.TXT , ser.Name 是 abcd.txt ,本身就是同一个文件,只不过大小写不同,
所以把它们统一转成大写(或小写)来进行比较。