请问两段代码的区别? ( 积分: 100 )

  • 主题发起人 主题发起人 fuzengbin
  • 开始时间 开始时间
F

fuzengbin

Unregistered / Unconfirmed
GUEST, unregistred user!
我的两段代码,第一段通过SaveDialog可以成功地创建一个Wav格式的文件,并把文字转成语音保存。而第二段代码,不想使用SaveDialog对话框,直接就生成一个Wav文件,却不行。请高手回答该怎样解决第二段代码的问题。(在线等待.....)
第一段:
if SaveDialog1.Execute then

begin

if not (DataSource1.DataSet.State in [dsedit]) then

DataSource1.DataSet.Edit;
DataSource1.DataSet.FieldByName('wavpath').AsString := SaveDialog1.FileName;
DataSource1.DataSet.Post;
try
SpFileStream1.Open(SaveDialog1.FileName,SSFMCreateForWrite,false);
SpVoice1.AudioOutputStream := SpFileStream1.DefaultInterface;
SpVoice1.Speak(DBRichEdit1.Text,SVSFlagsAsync);
SpVoice1.WaitUntilDone(SpVoice1.SynchronousSpeakTimeout);
SpFileStream1.Close;
except
MessageBox(handle,'你没有安装微软Speech SDK,该功能无法正常使用!','系统提示',MB_OK+MB_ICONINFORMATION);
end;

end;

第二段:
WavName:= ExtractFilePath(Application.ExeName)+'wav/'+DataSource1.DataSet.FieldByName('kssj').AsString+'.wav';
if not (DataSource1.DataSet.State in [dsedit]) then

DataSource1.DataSet.Edit;
DataSource1.DataSet.FieldByName('wavpath').AsString := WavName;
DataSource1.DataSet.Post;
CreateDirectory(PChar(ExtractFilePath(Application.ExeName)+'/wav'),nil);

CreateFile(PChar(WavName), GENERIC_WRITE, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
try
SpFileStream1.Open(WavName,SSFMCreateForWrite,false);
SpVoice1.AudioOutputStream := SpFileStream1.DefaultInterface;
SpVoice1.Speak(DBRichEdit1.Text,SVSFlagsAsync);
SpVoice1.WaitUntilDone(SpVoice1.SynchronousSpeakTimeout);
SpFileStream1.Close;
except
MessageBox(handle,'你没有安装微软Speech SDK,该功能无法正常使用!','系统提示',MB_OK+MB_ICONINFORMATION);
end;
 
我的两段代码,第一段通过SaveDialog可以成功地创建一个Wav格式的文件,并把文字转成语音保存。而第二段代码,不想使用SaveDialog对话框,直接就生成一个Wav文件,却不行。请高手回答该怎样解决第二段代码的问题。(在线等待.....)
第一段:
if SaveDialog1.Execute then

begin

if not (DataSource1.DataSet.State in [dsedit]) then

DataSource1.DataSet.Edit;
DataSource1.DataSet.FieldByName('wavpath').AsString := SaveDialog1.FileName;
DataSource1.DataSet.Post;
try
SpFileStream1.Open(SaveDialog1.FileName,SSFMCreateForWrite,false);
SpVoice1.AudioOutputStream := SpFileStream1.DefaultInterface;
SpVoice1.Speak(DBRichEdit1.Text,SVSFlagsAsync);
SpVoice1.WaitUntilDone(SpVoice1.SynchronousSpeakTimeout);
SpFileStream1.Close;
except
MessageBox(handle,'你没有安装微软Speech SDK,该功能无法正常使用!','系统提示',MB_OK+MB_ICONINFORMATION);
end;

end;

第二段:
WavName:= ExtractFilePath(Application.ExeName)+'wav/'+DataSource1.DataSet.FieldByName('kssj').AsString+'.wav';
if not (DataSource1.DataSet.State in [dsedit]) then

DataSource1.DataSet.Edit;
DataSource1.DataSet.FieldByName('wavpath').AsString := WavName;
DataSource1.DataSet.Post;
CreateDirectory(PChar(ExtractFilePath(Application.ExeName)+'/wav'),nil);

CreateFile(PChar(WavName), GENERIC_WRITE, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
try
SpFileStream1.Open(WavName,SSFMCreateForWrite,false);
SpVoice1.AudioOutputStream := SpFileStream1.DefaultInterface;
SpVoice1.Speak(DBRichEdit1.Text,SVSFlagsAsync);
SpVoice1.WaitUntilDone(SpVoice1.SynchronousSpeakTimeout);
SpFileStream1.Close;
except
MessageBox(handle,'你没有安装微软Speech SDK,该功能无法正常使用!','系统提示',MB_OK+MB_ICONINFORMATION);
end;
 
这句好象没必要吧
CreateFile(PChar(WavName), GENERIC_WRITE, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
它会导致以下的代码没有读写该文件
 
去掉后也不行啊
 
WavName:= ExtractFilePath(Application.ExeName)+'/wav/'+DataSource1.DataSet.FieldByName('kssj').AsString+'.wav';
 
CreateDirectory(PChar(ExtractFilePath(Application.ExeName)+'/wav'),nil);
改为
CreateDirectory(PChar(ExtractFilePath(Application.ExeName)+'wav'),nil);
 
应该是文件访问控制问题,仔细调试一下路径变量和文件控制问题
 
用filecreate不行吗?
 
前面的代码没有问题,关键是这句:
SpFileStream1.Open(WavName,SSFMCreateForWrite,false);
在执行是到speechlib_tlb库文件的过程:
procedure TSpFileStream.Open(const FileName: WideString;
FileMode: SpeechStreamFileMode;
DoEvents: WordBool);
begin

DefaultInterface.Open(FileName, FileMode,do
Events);
end;

时出错,错误信息是:
“.....找不到%1。.....”
 
其实cretefile或filecreate都是没有必要的,关键是SpFileStream1.Open(WavName,SSFMCreateForWrite,false);
无法执行成功
 
问题搞清楚了,是文件名组合的问题,如果把改为:
WavName:='D:/wav/abc.wav'则执行下面的语句就没有问题了。
看来问题是怎样把语句:WavName:= ExtractFilePath(Application.ExeName)+'wav/'+DataSource1.DataSet.FieldByName('kssj').AsString+'.wav';
给处理一下。但是不知道怎么处理。是字符串合并函数吗?
 
SpFileStream1.Open(WavName,SSFMCreateForWrite,false);
这个函数的第一个参数要求传递的是一个Const类型的参数,而我的Wav文件名必须动态产生,是个变量字符串,请问这如何解决啊!
 
离成功只有一步了,将代码改为下面的:
if not (DataSource1.DataSet.State in [dsedit]) then

DataSource1.DataSet.Edit;
DataSource1.DataSet.FieldByName('wavpath').AsString := WavName;
DataSource1.DataSet.Post;

FileDate:= DataSource1.DataSet.FieldByName('kssj').AsDateTime;
WavPath:=ExtractFilePath(Application.ExeName)+'wav/';

CreateDirectory(PChar(WavPath),nil);
WavName:=WavPath+FormatDateTime('yyyymmddhhmmss',FileDate)+'.wav';
FileCreate(WavName);
//已经实际创建成功了该文件!

try
SpFileStream1.Open(WavName,SSFMOpenReadWrite,false);
//Open中的文件模式 参数改为SSFMOpenReadWrite
SpVoice1.AudioOutputStream := SpFileStream1.DefaultInterface;
SpVoice1.Speak(DBRichEdit1.Text,SVSFlagsAsync);
SpVoice1.WaitUntilDone(SpVoice1.SynchronousSpeakTimeout);
SpFileStream1.Close;
except
MessageBox(handle,'你没有安装微软Speech SDK,该功能无法正常使用!','系统提示',MB_OK+MB_ICONINFORMATION);
end;

问题是调用SpFileStream1.Open(WavName,SSFMOpenReadWrite,false);时出现“参数不正确的提示”。关键还是传递的那个WavName参数类型的问题!请高手相助啊!
 
1.把合成的文件名ShowMessage出来,看是否合法
2.普通的CreateFile不能够自动创建没有的文件夹.比如如果不存在[D:/ABC],那么CreateFile('D:/ABC/a.txt'),就会出错.你只能逐层建立各级目录/SH...有一个API可以直接创建多级目录
 
我这里觉得可能是wav文件的格式不对产生了读写错误,在windows桌面上右键新建一个空的wav文件,用ultraedit打开可以发现一些wav文件的格式标识,用filecreate函数新建一个空白的文件不会自动写入这些文件信息,如果要创建的话,可能需要手动添加这些文件头信息,因为我没有SpFileStream相关控件,不能进一步调试,偶然发现这个问题提出做为参考。
 
为什么用SavDialog就可以啊?
 
用ForceDirectories(Dir:string)函数来创建目录;
 
用ForceDirectories(Dir:string)就可以解决问题,谢谢yzxcsw的指点!可惜还不清楚这个函数与createdirectory有什么区别?
 
后退
顶部