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的文章应该有所帮助. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |