ironfede / openmcdf

Microsoft Compound File .net component - pure C# - netstandard 2.0
Mozilla Public License 2.0
308 stars 76 forks source link

RootStorage Delete Unable to delete content #94

Closed wf-soft closed 1 year ago

wf-soft commented 1 year ago
var cf = new CompoundFile(@"D:\BaiduSyncdisk\WFsoft\Max文件研究\1.max", CFSUpdateMode.Update, CFSConfiguration.Default);
//Cf.RootStorage.GetStream("Scene").SetData(new byte[0]);
Cf.RootStorage.Delete("Scene");
Cf.Save(@"D:\BaiduSyncdisk\WFsoft\2.max");
Cf.Close();

In this way, I can only delete the block name, but not the data. When I use SetData and then Commit, the file will keep growing every time I save it

wf-soft commented 1 year ago

When I use CFSConfiguration.EraseFreeSectors is used, it just replaces byte with 0xFF, and cannot free space to reduce the file size. Then using SetData will cause the file to be larger each time it is modified

ironfede commented 1 year ago

Sorry for the delayed response @wf-soft. Current implementation doesn't reduce size without an explicit call to

CompoundFile.ShrinkCompoundFile(filename);

I've added a test to give an example of a possible strategy for file size reduction

String filename = "_Test.ppt";
String filename2 = "MyFile4.dat";

if (File.Exists(filename2))
     File.Delete(filename2);

if (File.Exists(filename))
{
   File.Copy(filename, filename2);
}

var cf = new CompoundFile(filename2, CFSUpdateMode.Update, CFSConfiguration.EraseFreeSectors);

cf.RootStorage.Delete("PowerPoint Document");

cf.Commit();

cf.Close();

CompoundFile.ShrinkCompoundFile(filename2);

long length = new System.IO.FileInfo(filename).Length;

long length2 = new System.IO.FileInfo(filename2).Length;

Assert.IsTrue(length > length2);

I hope this example may clarify the point. Best Regards, Federico

ironfede commented 1 year ago

Added example for #94

wf-soft commented 1 year ago

@ironfede What I am currently using is to copy the content to a new CompoundFile and save it. I will try your solution, Thank you for your answer