`DatabaseConnecton` constructor opens file but does not close it, causing errors
holly-hacker opened this issue · comments
When creating a DatabaseConnection
that needs to create a new file, it will do so by calling File.Create(filePath)
(as seen here). This method returns a FileStream
, which SliccDB does not close. As long as the garbage collector does not collect this object, the file will remain open and other operations that access it may fail.
Repro example:
for (int i = 0; i < 100; i++)
{
Console.WriteLine($"Iteration {i}");
File.Delete("test.db");
var db = new DatabaseConnection("test.db");
db.ClearDatabase();
}
This outputs the following for me:
Iteration 0
Unhandled exception. System.IO.IOException: The process cannot access the file 'D:\Projects\DotNet\eetool\eetool\bin\Debug\net6.0\test.db' because it is being used by another process.
at Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options)
at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
at System.IO.File.OpenHandle(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
at System.IO.File.WriteAllBytes(String path, Byte[] bytes)
at SliccDB.Serialization.DatabaseConnection.SaveDatabase() in D:\Projects\DotNet\eetool\SliccDB\SliccDB\Serialization\DatabaseConnection.cs:line 104
at SliccDB.Serialization.DatabaseConnection.ClearDatabase() in D:\Projects\DotNet\eetool\SliccDB\SliccDB\Serialization\DatabaseConnection.cs:line 121
at Program.<Main>$(String[] args) in D:\Projects\DotNet\eetool\eetool\Program.cs:line 15
at Program.<Main>(String[] args)
A solution could be to explicitly dispose this FileStream object, to use another method such as File.WriteAllText
, to not create the empty file or to serialize the empty database.
I am using the latest commit on the master branch, which currently is 9b6972e.
I decided to delete this line as it doesn't contribute to the functionality in any way. Great catch!