|
|
@@ -0,0 +1,70 @@ |
|
|
|
/***************************************************************************** |
|
|
|
Copyright 2021 The TensorFlow.NET Authors. All Rights Reserved. |
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
you may not use this file except in compliance with the License. |
|
|
|
You may obtain a copy of the License at |
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0 |
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software |
|
|
|
distributed under the License is distributed on an "AS IS" BASIS, |
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
|
|
See the License for the specific language governing permissions and |
|
|
|
limitations under the License. |
|
|
|
******************************************************************************/ |
|
|
|
|
|
|
|
using System; |
|
|
|
using System.IO; |
|
|
|
using System.IO.MemoryMappedFiles; |
|
|
|
using System.Linq; |
|
|
|
using Tensorflow; |
|
|
|
|
|
|
|
namespace Tensorflow.IO |
|
|
|
{ |
|
|
|
public class MemmappedFileSystem |
|
|
|
{ |
|
|
|
public const string MEMMAPPED_PACKAGE_DEFAULT_NAME = "memmapped_package://."; |
|
|
|
|
|
|
|
private MemoryMappedFile _mmapFile; |
|
|
|
private MemmappedFileSystemDirectory _directory; |
|
|
|
|
|
|
|
public MemmappedFileSystem(string path) |
|
|
|
{ |
|
|
|
using (var stream = File.OpenRead(path)) |
|
|
|
{ |
|
|
|
// Read the offset for the directory |
|
|
|
var offsetData = new byte[sizeof(ulong)]; |
|
|
|
stream.Seek(-sizeof(ulong), SeekOrigin.End); |
|
|
|
stream.Read(offsetData, 0, sizeof(ulong)); |
|
|
|
var offset = BitConverter.ToUInt64(offsetData, 0); |
|
|
|
|
|
|
|
var dirLength = stream.Length - (long) offset - sizeof(ulong); |
|
|
|
if (dirLength < 0) |
|
|
|
{ |
|
|
|
throw new InvalidDataException("Malformed mmapped filesystem!"); |
|
|
|
} |
|
|
|
|
|
|
|
var dirData = new byte[dirLength]; |
|
|
|
|
|
|
|
stream.Seek((long) offset, SeekOrigin.Begin); |
|
|
|
stream.Read(dirData, 0, (int) dirLength); |
|
|
|
|
|
|
|
_directory = MemmappedFileSystemDirectory.Parser.ParseFrom(dirData); |
|
|
|
} |
|
|
|
|
|
|
|
_mmapFile = MemoryMappedFile.CreateFromFile(path, FileMode.Open); |
|
|
|
} |
|
|
|
|
|
|
|
public Stream OpenMemmapped(string filename) |
|
|
|
{ |
|
|
|
var entry = _directory.Element.FirstOrDefault(x => x.Name == filename); |
|
|
|
if (entry == null) |
|
|
|
{ |
|
|
|
throw new FileNotFoundException($"Missing memmaped file entry: {filename}"); |
|
|
|
} |
|
|
|
|
|
|
|
return _mmapFile.CreateViewStream((long) entry.Offset, (long) entry.Length); |
|
|
|
} |
|
|
|
} |
|
|
|
} |