dmitry, you are welcome, please use this more stable and safe version.
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Rebex.IO.FileSystem;
namespace MemoryFs
{
public class SimpleMemoryProvider
: ReadWriteFileSystemProvider
{
private readonly Dictionary<NodePath, NodeBase> _pathToNodeDictionary;
private readonly Dictionary<NodeBase, FsNodeData> _storage;
public SimpleMemoryProvider() : this(null)
{
}
public SimpleMemoryProvider(FileSystemProviderSettings settings) : base(settings)
{
_pathToNodeDictionary = new Dictionary<NodePath, NodeBase>();
_storage = new Dictionary<NodeBase, FsNodeData>();
}
public void AddRoot()
{
init();
}
private Dictionary<NodeBase, FsNodeData> Storage
{
get
{
return _storage;
}
}
private Dictionary<NodePath, NodeBase> PathToNodeDictionary
{
get
{
return _pathToNodeDictionary;
}
}
protected override NodeAttributes GetAttributes(NodeBase node)
{
if (!node.Exists())
{
return node.Attributes;
}
return Storage[node].Attributes;
}
protected override NodeTimeInfo GetTimeInfo(NodeBase node)
{
return Storage[node].TimeInfo;
}
protected override NodeBase GetChild(string name, DirectoryNode parent)
{
return Storage[parent].Children.FirstOrDefault(child => child.Name == name);
}
protected override IEnumerable<NodeBase> GetChildren(DirectoryNode parent, NodeType nodeType)
{
if (!parent.Exists())
{
return Enumerable.Empty<NodeBase>();
}
var children = Storage[parent].Children;
return children;
}
protected override bool Exists(NodePath path, NodeType nodeType)
{
NodeBase node;
PathToNodeDictionary.TryGetValue(path, out node);
return node != null && node.NodeType == nodeType;
}
protected override long GetLength(NodeBase node)
{
if (!node.Exists())
{
return 0L;
}
return Storage[node].Length;
}
protected override NodeContent GetContent(NodeBase node, NodeContentParameters contentParameters)
{
if (!node.Exists())
{
//error
return NodeContent.CreateDelayedWriteContent(new MemoryStream());
}
var retStream = new MemoryStream();
Storage[node].Content.CopyTo(retStream);
retStream.Position = 0;
Storage[node].Content.Position = 0;
return contentParameters.AccessType == NodeContentAccess.Read
? NodeContent.CreateReadOnlyContent(retStream)
: NodeContent.CreateDelayedWriteContent(retStream);
}
protected override DirectoryNode CreateDirectory(DirectoryNode parent, DirectoryNode child)
{
return createCommon(parent, child) as DirectoryNode;
}
protected override FileNode CreateFile(DirectoryNode parent, FileNode child)
{
return createCommon(parent, child) as FileNode;
}
protected override NodeBase Delete(NodeBase node)
{
if (!node.Exists())
{
return node;
}
Storage.Remove(node);
PathToNodeDictionary.Remove(node.Path);
Storage[node.Parent].Children.Remove(node);
return node;
}
protected override NodeBase Rename(NodeBase node, string newName)
{
var isFile = node.NodeType == NodeType.File;
var newNode = isFile
? (NodeBase)new FileNode(newName,
node.Parent)
: new DirectoryNode(newName, node.Parent);
Delete(node);
return newNode;
}
protected override NodeBase SaveContent(NodeBase node, NodeContent content)
{
if (!node.Exists())
{
return node;
}
var myCurrentStream = new MemoryStream();
content.GetStream().CopyTo(myCurrentStream);
myCurrentStream.Position = 0;
Storage[node].Content = myCurrentStream;
return node;
}
protected override NodeBase SetAttributes(NodeBase node, NodeAttributes attributes)
{
Storage[node].Attributes = attributes;
return node;
}
protected override NodeBase SetTimeInfo(NodeBase node, NodeTimeInfo newTimeInfo)
{
Storage[node].TimeInfo = newTimeInfo;
return node;
}
private void init()
{
if (_storage.Count == 0)
{
_storage.Add(Root, new FsNodeData());
_pathToNodeDictionary.Add(Root.Path, Root);
}
}
private NodeBase createCommon(DirectoryNode parent, NodeBase child)
{
Storage.Add(child, new FsNodeData());
Storage[parent].Children.Add(child);
PathToNodeDictionary.Add(child.Path, child);
return child;
}
}
internal class FsNodeData
{
public FsNodeData()
{
Content = new MemoryStream();
TimeInfo = new NodeTimeInfo();
Children = new List<NodeBase>();
Attributes = new NodeAttributes(FileAttributes.Offline);
}
public NodeAttributes Attributes
{
get;
set;
}
public NodeTimeInfo TimeInfo
{
get;
set;
}
public List<NodeBase> Children
{
get;
set;
}
public long Length
{
get
{
return Content.Length;
}
}
public MemoryStream Content { get; set; }
}
}
//Usage: