Update: Rebex File Server 2017 R4 adds virtual file systems support. See the latest answer for details.
Although virtual file systems are not supported yet, Rebex File Server internals were designed with this scenario in mind and we plan to add a simple-to-use high-level API for this soon.
However, if you can't wait, you can try the Rebex File Server Beta with proof-of-concept IFilesystem interface and the related objects:
interface IFilesystem
{
IHandle OpenDirectory(string path, string mask);
IHandle OpenFile(string path, FileOpenMode openMode, FileAccessMode accessMode);
void Close(IHandle handle);
ItemInfo ReadNextItem(IHandle handle);
int Read(IHandle handle, byte[] buffer, int offset, int count);
void Write(IHandle handle, byte[] buffer, int offset, int count);
long Seek(IHandle handle, FileSeekOrigin origin, long offset);
void CreateDirectory(string path);
void DeleteDirectory(string path);
void DeleteFile(string path);
ItemInfo GetItemInfo(string path);
void SetItemInfo(IHandle handle, ItemInfo info);
void SetItemInfo(string path, ItemInfo info);
void Rename(string sourcePath, string targetPath);
FilesystemInfo GetFilesystemInfo();
string Normalize(string absolutePath);
string ResolvePath(string path, string relativePath);
}
This is a bit more low-level that we would like, but on the other hand it makes it possible to implement a virtual file system that is completely independent of the actual file system on disk. I will mail you a download link.
To get started, try the following code. It implements a FileServerEx
class that inherits from FileServer
, but wraps the original file system object in a custom class that can be extended to do something else. For example, the OpenFile
method can be modified to return a custom IHandle
instead of calling _inner.OpenFile
, and other methods that accept IHandle
can be enhanced to handle both custom and built-in IHandles
. Depending on your scenario, you will probably want to ignore the built-in IFilesystem
implementations and write a complete custom filesystem from scratch.
public class FileServerExt : FileServer
{
private class FilesystemWrapper : IFilesystem
{
private readonly IFilesystem _inner;
public FilesystemWrapper(IFilesystem inner)
{
_inner = inner;
}
void IFilesystem.Close(IHandle handle)
{
_inner.Close(handle);
}
void IFilesystem.CreateDirectory(string path)
{
_inner.CreateDirectory(path);
}
void IFilesystem.DeleteDirectory(string path)
{
_inner.DeleteDirectory(path);
}
void IFilesystem.DeleteFile(string path)
{
_inner.DeleteFile(path);
}
FilesystemInfo IFilesystem.GetFilesystemInfo()
{
return _inner.GetFilesystemInfo();
}
ItemInfo IFilesystem.GetItemInfo(string path)
{
return _inner.GetItemInfo(path);
}
string IFilesystem.Normalize(string absolutePath)
{
return _inner.Normalize(absolutePath);
}
IHandle IFilesystem.OpenDirectory(string path, string mask)
{
return _inner.OpenDirectory(path, mask);
}
IHandle IFilesystem.OpenFile(string path, FileOpenMode openMode, FileAccessMode accessMode)
{
return _inner.OpenFile(path, openMode, accessMode);
}
int IFilesystem.Read(IHandle handle, byte[] buffer, int offset, int count)
{
return _inner.Read(handle, buffer, offset, count);
}
ItemInfo IFilesystem.ReadNextItem(IHandle handle)
{
return _inner.ReadNextItem(handle);
}
void IFilesystem.Rename(string sourcePath, string targetPath)
{
_inner.Rename(sourcePath, targetPath);
}
string IFilesystem.ResolvePath(string path, string relativePath)
{
return _inner.ResolvePath(path, relativePath);
}
long IFilesystem.Seek(IHandle handle, FileSeekOrigin origin, long offset)
{
return _inner.Seek(handle, origin, offset);
}
void IFilesystem.SetItemInfo(string path, ItemInfo info)
{
_inner.SetItemInfo(path, info);
}
void IFilesystem.SetItemInfo(IHandle handle, ItemInfo info)
{
_inner.SetItemInfo(handle, info);
}
void IFilesystem.Write(IHandle handle, byte[] buffer, int offset, int count)
{
_inner.Write(handle, buffer, offset, count);
}
}
protected override IFilesystem GetFilesystem(ServerUser user)
{
IFilesystem inner = base.GetFilesystem(user);
IFilesystem outer = new FilesystemWrapper(inner);
return outer;
}
}
Please note that when using the FileServerExt class intead of FileServer class, user’s virtualRootPath still applies, making it possible for different users to access different parts of the custom filesystem.
Other users that want to test beta version, write us to support@rebex.net.