0 votes
by (400 points)

Hello, I'm trying to receive the file in custom realisation of FileSystem and move it without saving on remote server. For that, I need to get the stream of file, how can I do that in such method?


    /// <inheritdoc />
    protected override FileNode CreateFile(DirectoryNode parent, FileNode child)
        //// second throw;
        FileStream file = File.Open(child.Path.StringPath, FileMode.Open);
        throw new NotImplementedException();
Applies to: Rebex SFTP

1 Answer

+1 vote
by (5.3k points)
selected by
Best answer

Method protected override FileNode CreateFile(DirectoryNode parent, FileNode child) should create empty file.

I think that this method is not suitable for your scenario.

I am assuming from other information you have provided (http://forum.rebex.net/8351/possibility-to-catch-the-beggining-of-file-transfer) that you are now using LocalFileSystemProvider (https://www.rebex.net/file-server/features/virtual-file-systems.aspx#local-provider) or other virtual file system provider).

Please be aware that for the SFTP server you should have full-fledged file system (built-in LocalFileSystemProvider/MemoryFileSystemProvider or custom file system provider for the remote server or custom file system provider that combines characteristics of the local and remote file system behavior).

All file system providers publish events/hooks:

    //Get notifier
    FileSystemNotifier notifier = localFS.GetFileSystemNotifier();
    //GetFileSystemNotifier() is extension method

//You can replace implementation of the GetContent method.
notifier.GetContentSurrogate += (sender, args) =>
    //analyze args.Node, args.ContentParameters and decide how to handle request
    if (args.Node.IsFile && openForWriteRequest(args))
        var streamForWrite = new MemoryStream(); //or open your custom special server stream

        //Create the delayed write content. Delayed = I will save new content of the file later - when the upload of the file finished.
        args.ResultContent = NodeContent.CreateDelayedWriteContent(streamForWrite);

//You can replace implementation of the SaveContent method.
notifier.SetContentSurrogate += (sender, args) =>
        //Decide what to do with stream
        if (needsSaveOnRemoteServer(args))
            var fileStream = args.Content.GetStream();
            //apply your logic - save the fileStream on the server

            //We are done, do not call SaveContent method on the local file system provider.

by (400 points)
reshown by
So that means if I didn't apply saving the file is storing in RAM, right? Even if I use LocalFileSystem.
by (400 points)
btw, thanks for answer!
by (5.3k points)
edited by
You are welcome. I am not sure if I understand what the sentence "if I didn't apply saving the file is storing in RAM" means:

1) If you decide to use LocalFileSystemProvider and GetContent/SetContent hooks, then you will store on local file system only file "stubs"  - empty files without content. Uploaded data will be temporarily stored in MemoryStream.
2) If you decide to use MemoryFileSystemProvider and GetContent/SetContent hooks, then again - you will store only file "stubs" in memory. The main difference between the two mentioned approaches lies in the fact that directory structure and files (stubs) contained in the MemoryFileSystemProvider will be destroyed every time the process of the sftp server will be terminated.
In case you will try to use the MemoryFileSystemProvider you (probably) should somehow restore the filesystem structure immediately after the next start of the sftp server.

Using the LocalFileSystemProvider has the following advantages:

1) File content is not stored locally (as requested).
2) And Directory/file (stubs) structure is preserved between the sftp server runs.
by (400 points)
I don't need to keep directories structure.
I need more like using the security part of SFTP protocol without file system just for receive the file and move it further to Azure Data Lake.
Anyway, thanks for answers, I'll try your suggestion.
by (5.3k points)
Then MemoryFileSystemProvider seems to be your best friend  at the moment:)