当我运行下面的程序时,stgOpenStorage的结果值是STG_E_SHAREVIOLATION。我应该如何关闭iStorage才能将其解锁?
procedure TForm1.btnSaveClick(Sender: TObject);
var
fileName : string;
streamName : string;
procedure storeTextIntoStorageStream( text_ : string );
var
documentStorage : IStorage;
levelIStream : IStream;
i, j : integer;
begin
if ( fileExists( fileName ) ) then
deleteFile( fileName );
stgCreateDocfile( @fileName[1], STGM_WRITE or STGM_SHARE_EXCLUSIVE or STGM_DIRECT or STGM_CREATE, 0, documentStorage );
try
documentStorage.CreateStream( @streamName[1], STGM_WRITE or STGM_SHARE_EXCLUSIVE or STGM_DIRECT, 0, 0, levelIStream );
try
i := length( text_ );
levelIStream.write( @i, sizeOf( integer ), @j );
levelIStream.write( @text_[1], i*sizeOf( char ), @j );
finally
levelIStream.Commit( 0 );
levelIStream := NIL;
end;
finally
documentStorage.Commit( 0 );
documentStorage := NIL;
end;
end;
function readTextFromStorageStream : string;
var
documentStorage : IStorage;
levelIStream : IStream;
i, j : integer;
begin
i := stgOpenStorage( @fileName[1], NIL, STGM_READ or STGM_SHARE_EXCLUSIVE or STGM_DIRECT, NIL, 0, documentStorage );
try
documentStorage.OpenStream( @streamName[1], NIL, STGM_READ or STGM_SHARE_EXCLUSIVE or STGM_DIRECT, 0, levelIStream );
try
levelIStream.read( @i, sizeOf( integer ), @j );
setLength( result, i );
levelIStream.read( @result[1], i*sizeOf( char ), @j );
finally
levelIStream := NIL;
end;
finally
documentStorage := NIL;
end;
end;
begin
fileName := 'c:temptest.stg';
streamName := 'Stream-0';
storeTextIntoStorageStream( memo1.Lines.DelimitedText );
memo1.Lines.DelimitedText := readTextFromStorageStream;
end;
如何设置IStorage/IStream默认大小/大小步长?因为我的测试1.6K字节的内容存储在16K。
2条答案
按热度按时间7gcisfzg1#
将引用设置为零是不够的。由操作系统内存管理器创建的IStorage/IStream示例,而不是分配给应用程序的示例。如果我们将app变量的值设置为nil,则只会自动调用app内存管理器。唯一可以释放分配给该示例的内存的是操作系统内存管理器。对示例的释放调用调用此内存管理器。
在设置为nil之前调用接口上的Release方法:
hgqdbh6s2#
代码看起来没问题,所以我觉得这个问题是由于您使用
STGM_SHARE_EXCLUSIVE
造成的。当你试图打开文件时,文件正在使用中,所以我打赌是你的OS/AV让文件保持打开(即扫描其内容),而不是storeTextIntoStorageStream()
中的界面,当readTextFromStorageStream()
进入时,这些界面早就消失了。他说:嗯,除了缺乏足够的错误处理外。以及接口变量的冗余
nil
‘ing。并且,可以考虑将字符串索引替换为PChar()
强制转换。在
readTextFromStorageStream()
中,尝试用STGM_SHARE_DENY_WRITE
替换STGM_SHARE_EXCLUSIVE
(这对写入器有意义,但对读取器没有意义),并查看错误是否消失: