加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 从文件夹中读取无效的文件名

发布时间:2020-12-15 04:17:20 所属栏目:大数据 来源:网络整理
导读:我有一个有趣的问题.我们的客户通过电话录制了语音对话,但是录制的文件名无效.以下是文件名123:123.wmv??的示例 相信它,Windows Media编码器创建了文件,所有信息都在文件中,但是Windows显然无法识别文件名,只在文件夹中显示为123,文件为0KB 从这里开始编辑
我有一个有趣的问题.我们的客户通过电话录制了语音对话,但是录制的文件名无效.以下是文件名123:123.wmv??的示例

相信它,Windows Media编码器创建了文件,所有信息都在文件中,但是Windows显然无法识别文件名,只在文件夹中显示为123,文件为0KB

从这里开始编辑:感谢Keith Miller向我指出了正确的方向,我可以编写一个函数,从文件中提取流名称并使用它.

我已经包含了如何在文件中创建两个数据流,读取流名称和从每个流中读取数据的工作副本.这非常棒,所以我希望其他人也可以使用它.
我的代码忽略了主流.如果将数据写入主流,最好不要忽略它.

unit Unit1;

interface

uses
  Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,Dialogs,StdCtrls,uGeneralStuff;

type
  _FILE_STREAM_INFORMATION = record
    NextEntryOffset: cardinal;
    StreamNameLength: cardinal;
    StreamSize: int64;
    StreamAllocationSize: int64;
    StreamName: array[0..MAX_PATH] of WideChar;
  end;

  PFILE_STREAM_INFORMATION = ^_FILE_STREAM_INFORMATION;

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    InfoBlock: _FILE_STREAM_INFORMATION;
    StatusBlock : record
      Status: Cardinal;
      Information: PDWORD;
    end;

    procedure CreateFile(FileName,Info: String);
    function ReadFile(FileName: String): String;
    function ReadStreams(filename: String): TStringList;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

function NtQueryInformationFile(FileHandle : Cardinal;
                                  IoStatusBlock : Pointer;
                                  FileInformation : Pointer;
                                  FileInformationLength : Cardinal;
                                  FileInformationClass : Cardinal
                                  ): Cardinal; stdcall; external 'ntdll.dll';
implementation

uses Math,StrUtils;
{$R *.dfm}

function TForm1.ReadStreams(filename: String): TStringList;
var
  iFH1: Integer;
  aFileName: array[0..MAX_PATH] of WideChar;
  aStreamName: String;
begin
Result := TStringList.Create;
iFH1 := FileOpen(filename,GENERIC_READ);
NtQueryInformationFile(iFH1,@StatusBlock,@InfoBlock,SizeOf(InfoBlock),22);  // 22 Means FileStreamInformation
FileClose(iFH1);
while (1=1) do
  begin
  if InfoBlock.StreamNameLength = 0 then
    break;
  CopyMemory(@aFileName,@InfoBlock.StreamName,InfoBlock.StreamNameLength);
  aStreamName := Copy(aFileName,1,PosEx(':',aFileName,2) - 1);
  if aStreamName <> ':' then   //Ignore main stream,because I know I didn't write data in there
    Result.Add(aStreamName);
  if (InfoBlock.NextEntryOffset = 0) then
    break;
  InfoBlock := PFILE_STREAM_INFORMATION(PByte(@InfoBlock) + InfoBlock.NextEntryOffset)^;
  end;
end;


procedure TForm1.Button2Click(Sender: TObject);
var
  aStreams: TStringList;
  I: Integer;
begin
aStreams := ReadStreams('C:Temp123');
for I := 0 to aStreams.Count - 1 do
  begin
  ShowMessage(ReadFile('C:Temp123' + aStreams[I]));
  end;
end;

procedure TForm1.CreateFile(FileName,Info: String);
var
  iFH1: Integer;
  Buffer: PAnsiString;
begin
  iFH1 := FileCreate(FileName);
  Buffer := PAnsiString(AnsiString(Info) + #0);
  FileWrite(iFH1,Buffer^,Length(Info));
  FileClose(iFH1);
end;

function TForm1.ReadFile(FileName: String): String;
var
  iFH1: Integer;
  Buffer: PAnsiChar;
  iFL: Integer;
  iBR,iCurPos,iReadSize: Integer;
begin
  iFH1 := FileOpen(FileName,GENERIC_READ);
  iFL := FileSeek(iFH1,2);
  FileSeek(iFH1,0);
  iReadSize := Min(iFL,1024);
  Buffer := AllocMem(iReadSize + 1);
  iCurPos := 0;
  Result := '';
  while iCurPos < iFL do
    begin
    iBR := FileRead(iFH1,iReadSize);
    if iBR = -1 then
      break;
    Result := Result + Buffer;
    Inc(iCurPos,iBR);
    end;
  FileClose(iFH1);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  CreateFile('C:Temp123:123.txt','This is TestFile 1');
  CreateFile('C:Temp123:345.txt','This is TestFile 2');
  ShowMessage(ReadFile('C:Temp123:123.txt'));
  ShowMessage(ReadFile('C:Temp123:345.txt'));
end;

end.

解决方法

在文件名中使用:在文件中创建备用数据流.请参阅文章
http://support.microsoft.com/kb/105763

在您的示例中,文件名为123,流称为123.wmv??.您可以编写一个程序来从文件中提取流,并使用传统的文件名重写它.

http://www.flexhex.com/docs/articles/alternate-streams.phtml的文章应该有所帮助.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读