NetTopologySuite / NetTopologySuite.IO.ShapeFile

The ShapeFile IO module for NTS.
35 stars 25 forks source link

Writing shape files with streams throws System.ObjectDisposedException 'Cannot access a closed file.' #8

Closed airbreather closed 3 months ago

airbreather commented 6 years ago

From @majorbenks on March 16, 2018 8:35

I tried to use ShapefileDataWriter with a ShapefileStreamProviderRegistry. I open four FileStreams and wrap them in an object implementing IShapefileStreamProvider adding them to a ShapefileStreamProviderRegistry. When I run my code, a System.ObjectDisposedException 'Cannot access a closed file.' is thrown. My code works fine when I use a file path instead of streams.

Hier is my the code:


            using (var shpStream = File.Create(Path.Combine(pathWithoutFilename, $"{fileNameWithoutEnding}.shp")))
            {
                using (var shxStream = File.Create(Path.Combine(pathWithoutFilename, $"{fileNameWithoutEnding}.shx")))
                {
                    using (var dbfStream = File.Create(Path.Combine(pathWithoutFilename, $"{fileNameWithoutEnding}.dbf")))
                    {
                        using (var prjStream = File.Create(Path.Combine(pathWithoutFilename, $"{fileNameWithoutEnding}.prf")))
                        {
                            var registry = new ShapefileStreamProviderRegistry(
                                            new ShapeFileStreamProvider(shpStream, StreamTypes.Shape),
                                            new ShapeFileStreamProvider(shxStream, StreamTypes.Index),
                                            new ShapeFileStreamProvider(dbfStream, StreamTypes.Data));

                            // Create the projection file
                            using (var streamWriter = new StreamWriter(prjStream))
                            {
                                streamWriter.Write(shapeFilePrjString);
                            }

                            // Create the shapefile
                            var outGeomFactory = GeometryFactory.Default;
                            var writer = new ShapefileDataWriter(registry, outGeomFactory, Encoding.UTF8);
                            var outDbaseHeader = ShapefileDataWriter.GetHeader(features[0], features.Count);
                            writer.Header = outDbaseHeader;
                            writer.Write(features);
                        }
                    }
                }
            }

This is the stack trace:

at System.IO.__Error.FileNotOpen() at System.IO.FileStream.Flush(Boolean flushToDisk) at System.IO.FileStream.Flush() at System.IO.BinaryWriter.Flush() at System.IO.BinaryWriter.get_BaseStream() at NetTopologySuite.IO.DbaseFileWriter.Write(DbaseFileHeader header) at NetTopologySuite.IO.ShapefileDataWriter.Write(IList1 featureCollection) at Softec.GIS.GeometrieDatenImportExport.FileAccess.SaveToShapeFile(String pathWithoutFilename, String fileNameWithoutEnding, String shapeFilePrjString, IList1 features) in C:\Projekte\Softec.GIS.GeometrieDatenImportExport.Console\Softec.GIS.GeometrieDatenImportExport\FileAccess.cs:line 72 at Softec.GIS.GeometrieDatenImportExport.ShapeExporter.ExportToShapeFile(List`1 models, String pathWithoutFilename, String fileNameWithoutEnding) in C:\Projekte\Softec.GIS.GeometrieDatenImportExport.Console\Softec.GIS.GeometrieDatenImportExport\ShapeExporter.cs:line 82 at Softec.GIS.GeometrieDatenImportExport.Console.Program.Main(String[] args) in C:\Projekte\Softec.GIS.GeometrieDatenImportExport.Console\Softec.GIS.GeometrieDatenImportExport.Console\Program.cs:line 31

Google research suggests, that the stream is closed somewhere, but I can't figure out where. I don't close it anywhere. Can anyone help? Or is this a bug?

I'm using NetTopologySuite v1.14.0, NetTopologySuite.IO. v1.14.0.1, NET FW 4.6.1, WIN 10 Pro and it is a console application.

Copied from original issue: NetTopologySuite/NetTopologySuite#223

KubaSzostak commented 3 months ago

Support for a custom-managed stream, which allows shapes to be written to it, has been added in the successor library. There is also a sample code demonstrating how to use streams.