コード例 #1
0
ファイル: ServiceFactory.cs プロジェクト: LightCC/SSH.NET
        public ISftpFileReader CreateSftpFileReader(string fileName, ISftpSession sftpSession, uint bufferSize)
        {
            const int defaultMaxPendingReads = 3;

            // Issue #292: Avoid overlapping SSH_FXP_OPEN and SSH_FXP_LSTAT requests for the same file as this
            // causes a performance degradation on Sun SSH
            var openAsyncResult = sftpSession.BeginOpen(fileName, Flags.Read, null, null);
            var handle          = sftpSession.EndOpen(openAsyncResult);

            var statAsyncResult = sftpSession.BeginLStat(fileName, null, null);

            long?fileSize;
            int  maxPendingReads;

            var chunkSize = sftpSession.CalculateOptimalReadLength(bufferSize);

            // fallback to a default maximum of pending reads when remote server does not allow us to obtain
            // the attributes of the file
            try
            {
                var fileAttributes = sftpSession.EndLStat(statAsyncResult);
                fileSize        = fileAttributes.Size;
                maxPendingReads = Math.Min(10, (int)Math.Ceiling((double)fileAttributes.Size / chunkSize) + 1);
            }
            catch (SshException ex)
            {
                fileSize        = null;
                maxPendingReads = defaultMaxPendingReads;

                DiagnosticAbstraction.Log(string.Format("Failed to obtain size of file. Allowing maximum {0} pending reads: {1}", maxPendingReads, ex));
            }

            return(sftpSession.CreateFileReader(handle, sftpSession, chunkSize, maxPendingReads, fileSize));
        }
コード例 #2
0
        /// <summary>
        /// Initializes a new <see cref="SftpFileReader"/> instance with the specified handle,
        /// <see cref="ISftpSession"/> and the maximum number of pending reads.
        /// </summary>
        /// <param name="handle"></param>
        /// <param name="sftpSession"></param>
        /// <param name="chunkSize">The size of a individual read-ahead chunk.</param>
        /// <param name="maxPendingReads">The maximum number of pending reads.</param>
        /// <param name="fileSize">The size of the file, if known; otherwise, <c>null</c>.</param>
        public SftpFileReader(byte[] handle, ISftpSession sftpSession, uint chunkSize, int maxPendingReads, long?fileSize)
        {
            _handle              = handle;
            _sftpSession         = sftpSession;
            _chunkSize           = chunkSize;
            _fileSize            = fileSize;
            _semaphore           = new SemaphoreLight(maxPendingReads);
            _queue               = new Dictionary <int, BufferedRead>(maxPendingReads);
            _readLock            = new object();
            _readAheadCompleted  = new ManualResetEvent(false);
            _disposingWaitHandle = new ManualResetEvent(false);
            _waitHandles         = _sftpSession.CreateWaitHandleArray(_disposingWaitHandle, _semaphore.AvailableWaitHandle);

            StartReadAhead();
        }
コード例 #3
0
ファイル: SftpFile.cs プロジェクト: REALTOBIZ/SSH.NET
        /// <summary>
        /// Initializes a new instance of the <see cref="SftpFile"/> class.
        /// </summary>
        /// <param name="sftpSession">The SFTP session.</param>
        /// <param name="fullName">Full path of the directory or file.</param>
        /// <param name="attributes">Attributes of the directory or file.</param>
        /// <exception cref="ArgumentNullException"><paramref name="sftpSession"/> or <paramref name="fullName"/> is null.</exception>
        internal SftpFile(ISftpSession sftpSession, string fullName, SftpFileAttributes attributes)
        {
            if (sftpSession == null)
                throw new SshConnectionException("Client not connected.");

            if (attributes == null)
                throw new ArgumentNullException("attributes");

            if (fullName == null)
                throw new ArgumentNullException("fullName");

            _sftpSession = sftpSession;
            Attributes = attributes;

            Name = fullName.Substring(fullName.LastIndexOf('/') + 1);

            FullName = fullName;
        }
コード例 #4
0
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="T:System.IO.Stream"/> and optionally releases the managed resources.
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);

            if (_session != null)
            {
                if (disposing)
                {
                    lock (_lock)
                    {
                        if (_session != null)
                        {
                            _canRead  = false;
                            _canSeek  = false;
                            _canWrite = false;

                            if (_handle != null)
                            {
                                if (_session.IsOpen)
                                {
                                    if (_bufferOwnedByWrite)
                                    {
                                        FlushWriteBuffer();
                                    }

                                    if (_ownsHandle)
                                    {
                                        _session.RequestClose(_handle);
                                    }
                                }

                                _handle = null;
                            }

                            _session = null;
                        }
                    }
                }
            }
        }
コード例 #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SftpFile"/> class.
        /// </summary>
        /// <param name="sftpSession">The SFTP session.</param>
        /// <param name="fullName">Full path of the directory or file.</param>
        /// <param name="attributes">Attributes of the directory or file.</param>
        /// <exception cref="ArgumentNullException"><paramref name="sftpSession"/> or <paramref name="fullName"/> is null.</exception>
        internal SftpFile(ISftpSession sftpSession, string fullName, SftpFileAttributes attributes)
        {
            if (sftpSession == null)
            {
                throw new SshConnectionException("Client not connected.");
            }

            if (attributes == null)
            {
                throw new ArgumentNullException("attributes");
            }

            if (fullName == null)
            {
                throw new ArgumentNullException("fullName");
            }

            _sftpSession = sftpSession;
            Attributes   = attributes;

            Name = fullName.Substring(fullName.LastIndexOf('/') + 1);

            FullName = fullName;
        }
コード例 #6
0
ファイル: SftpClient.cs プロジェクト: delfinof/ssh.net
        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged ResourceMessages.</param>
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);

            if (disposing)
            {
                if (_sftpSession != null)
                {
                    _sftpSession.Dispose();
                    _sftpSession = null;
                }
            }
        }
コード例 #7
0
ファイル: SftpClient.cs プロジェクト: delfinof/ssh.net
        /// <summary>
        /// Called when client is disconnecting from the server.
        /// </summary>
        protected override void OnDisconnecting()
        {
            base.OnDisconnecting();

            // disconnect, dispose and dereference the SFTP session since we create a new SFTP session
            // on each connect
            if (_sftpSession != null)
            {
                _sftpSession.Disconnect();
                _sftpSession.Dispose();
                _sftpSession = null;
            }
        }
コード例 #8
0
ファイル: SftpClient.cs プロジェクト: delfinof/ssh.net
        /// <summary>
        /// Called when client is connected to the server.
        /// </summary>
        protected override void OnConnected()
        {
            base.OnConnected();

            _sftpSession = ServiceFactory.CreateSftpSession(Session, OperationTimeout, ConnectionInfo.Encoding);
            _sftpSession.Connect();
        }
コード例 #9
0
ファイル: SftpFileStream.cs プロジェクト: checkymander/sshiva
        internal SftpFileStream(ISftpSession session, string path, FileMode mode, FileAccess access, int bufferSize)
        {
            if (session == null)
            {
                throw new SshConnectionException("Client not connected.");
            }
            if (path == null)
            {
                throw new ArgumentNullException("path");
            }
            if (bufferSize <= 0)
            {
                throw new ArgumentOutOfRangeException("bufferSize");
            }

            Timeout = TimeSpan.FromSeconds(30);
            Name    = path;

            // Initialize the object state.
            _session  = session;
            _canRead  = (access & FileAccess.Read) != 0;
            _canSeek  = true;
            _canWrite = (access & FileAccess.Write) != 0;

            var flags = Flags.None;

            switch (access)
            {
            case FileAccess.Read:
                flags |= Flags.Read;
                break;

            case FileAccess.Write:
                flags |= Flags.Write;
                break;

            case FileAccess.ReadWrite:
                flags |= Flags.Read;
                flags |= Flags.Write;
                break;

            default:
                throw new ArgumentOutOfRangeException("access");
            }

            if ((access & FileAccess.Read) != 0 && mode == FileMode.Append)
            {
                throw new ArgumentException(string.Format("{0} mode can be requested only when combined with write-only access.", mode.ToString("G")));
            }

            if ((access & FileAccess.Write) == 0)
            {
                if (mode == FileMode.Create || mode == FileMode.CreateNew || mode == FileMode.Truncate || mode == FileMode.Append)
                {
                    throw new ArgumentException(string.Format("Combining {0}: {1} with {2}: {3} is invalid.",
                                                              typeof(FileMode).Name,
                                                              mode,
                                                              typeof(FileAccess).Name,
                                                              access));
                }
            }

            switch (mode)
            {
            case FileMode.Append:
                flags |= Flags.Append | Flags.CreateNewOrOpen;
                break;

            case FileMode.Create:
                _handle = _session.RequestOpen(path, flags | Flags.Truncate, true);
                if (_handle == null)
                {
                    flags |= Flags.CreateNew;
                }
                else
                {
                    flags |= Flags.Truncate;
                }
                break;

            case FileMode.CreateNew:
                flags |= Flags.CreateNew;
                break;

            case FileMode.Open:
                break;

            case FileMode.OpenOrCreate:
                flags |= Flags.CreateNewOrOpen;
                break;

            case FileMode.Truncate:
                flags |= Flags.Truncate;
                break;

            default:
                throw new ArgumentOutOfRangeException("mode");
            }

            if (_handle == null)
            {
                _handle = _session.RequestOpen(path, flags);
            }

            // instead of using the specified buffer size as is, we use it to calculate a buffer size
            // that ensures we always receive or send the max. number of bytes in a single SSH_FXP_READ
            // or SSH_FXP_WRITE message

            _readBufferSize  = (int)session.CalculateOptimalReadLength((uint)bufferSize);
            _writeBufferSize = (int)session.CalculateOptimalWriteLength((uint)bufferSize, _handle);

            if (mode == FileMode.Append)
            {
                var attributes = _session.RequestFStat(_handle, false);
                _position = attributes.Size;
            }
        }
コード例 #10
0
ファイル: SftpFileStream.cs プロジェクト: sshnet/SSH.NET
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="T:System.IO.Stream"/> and optionally releases the managed resources.
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);

            if (_session != null)
            {
                if (disposing)
                {
                    lock (_lock)
                    {
                        if (_session != null)
                        {
                            _canRead = false;
                            _canSeek = false;
                            _canWrite = false;

                            if (_handle != null)
                            {
                                if (_session.IsOpen)
                                {
                                    if (_bufferOwnedByWrite)
                                    {
                                        FlushWriteBuffer();
                                    }

                                    if (_ownsHandle)
                                    {
                                        _session.RequestClose(_handle);
                                    }
                                }

                                _handle = null;
                            }

                            _session = null;
                        }
                    }
                }
            }
        }
コード例 #11
0
ファイル: SftpFileStream.cs プロジェクト: sshnet/SSH.NET
        internal SftpFileStream(ISftpSession session, string path, FileMode mode, FileAccess access, int bufferSize, bool useAsync)
        {
            // Validate the parameters.
            if (session == null)
                throw new SshConnectionException("Client not connected.");

            if (path == null)
            {
                throw new ArgumentNullException("path");
            }
            if (bufferSize <= 0)
            {
                throw new ArgumentOutOfRangeException("bufferSize");
            }
            if (access < FileAccess.Read || access > FileAccess.ReadWrite)
            {
                throw new ArgumentOutOfRangeException("access");
            }
            if (mode < FileMode.CreateNew || mode > FileMode.Append)
            {
                throw new ArgumentOutOfRangeException("mode");
            }

            Timeout = TimeSpan.FromSeconds(30);
            Name = path;

            // Initialize the object state.
            _session = session;
            _ownsHandle = true;
            _isAsync = useAsync;
            _bufferPosition = 0;
            _bufferLen = 0;
            _bufferOwnedByWrite = false;
            _canRead = ((access & FileAccess.Read) != 0);
            _canSeek = true;
            _canWrite = ((access & FileAccess.Write) != 0);
            _position = 0;
            _serverFilePosition = 0;

            var flags = Flags.None;

            switch (access)
            {
                case FileAccess.Read:
                    flags |= Flags.Read;
                    break;
                case FileAccess.Write:
                    flags |= Flags.Write;
                    break;
                case FileAccess.ReadWrite:
                    flags |= Flags.Read;
                    flags |= Flags.Write;
                    break;
            }

            switch (mode)
            {
                case FileMode.Append:
                    flags |= Flags.Append;
                    break;
                case FileMode.Create:
                    _handle = _session.RequestOpen(path, flags | Flags.Truncate, true);
                    if (_handle == null)
                    {
                        flags |= Flags.CreateNew;
                    }
                    else
                    {
                        flags |= Flags.Truncate;
                    }
                    break;
                case FileMode.CreateNew:
                    flags |= Flags.CreateNew;
                    break;
                case FileMode.Open:
                    break;
                case FileMode.OpenOrCreate:
                    flags |= Flags.CreateNewOrOpen;
                    break;
                case FileMode.Truncate:
                    flags |= Flags.Truncate;
                    break;
            }

            if (_handle == null)
                _handle = _session.RequestOpen(path, flags);

            _attributes = _session.RequestFStat(_handle);

            // instead of using the specified buffer size as is, we use it to calculate a buffer size
            // that ensures we always receive or send the max. number of bytes in a single SSH_FXP_READ
            // or SSH_FXP_WRITE message

            _readBufferSize = (int)session.CalculateOptimalReadLength((uint)bufferSize);
            _readBuffer = new byte[_readBufferSize];
            _writeBufferSize = (int)session.CalculateOptimalWriteLength((uint)bufferSize, _handle);
            _writeBuffer = new byte[_writeBufferSize];

            if (mode == FileMode.Append)
            {
                _position = _attributes.Size;
                _serverFilePosition = (ulong)_attributes.Size;
            }
        }
コード例 #12
0
ファイル: SftpFileStream.cs プロジェクト: sshnet/SSH.NET
 internal SftpFileStream(ISftpSession session, string path, FileMode mode, FileAccess access, int bufferSize)
     : this(session, path, mode, access, bufferSize, false)
 {
 }
コード例 #13
0
        internal SftpFileStream(ISftpSession session, string path, FileMode mode, FileAccess access, int bufferSize, bool useAsync)
        {
            // Validate the parameters.
            if (session == null)
            {
                throw new SshConnectionException("Client not connected.");
            }

            if (path == null)
            {
                throw new ArgumentNullException("path");
            }
            if (bufferSize <= 0)
            {
                throw new ArgumentOutOfRangeException("bufferSize");
            }
            if (access < FileAccess.Read || access > FileAccess.ReadWrite)
            {
                throw new ArgumentOutOfRangeException("access");
            }
            if (mode < FileMode.CreateNew || mode > FileMode.Append)
            {
                throw new ArgumentOutOfRangeException("mode");
            }

            Timeout = TimeSpan.FromSeconds(30);
            Name    = path;

            // Initialize the object state.
            _session            = session;
            _ownsHandle         = true;
            _isAsync            = useAsync;
            _bufferPosition     = 0;
            _bufferLen          = 0;
            _bufferOwnedByWrite = false;
            _canRead            = ((access & FileAccess.Read) != 0);
            _canSeek            = true;
            _canWrite           = ((access & FileAccess.Write) != 0);
            _position           = 0;
            _serverFilePosition = 0;

            var flags = Flags.None;

            switch (access)
            {
            case FileAccess.Read:
                flags |= Flags.Read;
                break;

            case FileAccess.Write:
                flags |= Flags.Write;
                break;

            case FileAccess.ReadWrite:
                flags |= Flags.Read;
                flags |= Flags.Write;
                break;
            }

            switch (mode)
            {
            case FileMode.Append:
                flags |= Flags.Append;
                break;

            case FileMode.Create:
                _handle = _session.RequestOpen(path, flags | Flags.Truncate, true);
                if (_handle == null)
                {
                    flags |= Flags.CreateNew;
                }
                else
                {
                    flags |= Flags.Truncate;
                }
                break;

            case FileMode.CreateNew:
                flags |= Flags.CreateNew;
                break;

            case FileMode.Open:
                break;

            case FileMode.OpenOrCreate:
                flags |= Flags.CreateNewOrOpen;
                break;

            case FileMode.Truncate:
                flags |= Flags.Truncate;
                break;
            }

            if (_handle == null)
            {
                _handle = _session.RequestOpen(path, flags);
            }

            _attributes = _session.RequestFStat(_handle);

            _readBufferSize  = (int)session.CalculateOptimalReadLength((uint)bufferSize);
            _readBuffer      = new byte[_readBufferSize];
            _writeBufferSize = (int)session.CalculateOptimalWriteLength((uint)bufferSize, _handle);
            _writeBuffer     = new byte[_writeBufferSize];

            if (mode == FileMode.Append)
            {
                _position           = _attributes.Size;
                _serverFilePosition = (ulong)_attributes.Size;
            }
        }
コード例 #14
0
 internal SftpFileStream(ISftpSession session, string path, FileMode mode, FileAccess access, int bufferSize)
     : this(session, path, mode, access, bufferSize, false)
 {
 }
コード例 #15
0
ファイル: SftpClient.cs プロジェクト: sshnet/SSH.NET
        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);

            if (disposing)
            {
                var sftpSession = _sftpSession;
                if (sftpSession != null)
                {
                    _sftpSession = null;
                    sftpSession.Dispose();
                }
            }
        }
コード例 #16
0
        internal SftpContextStream(ISftpSession session, string path, FileMode mode, FileAccess access,
                                   SftpFileAttributes attributes)
        {
            Flags flags = Flags.None;

            switch (access)
            {
            case FileAccess.Read:
                flags = Flags.Read;
                break;

            case FileAccess.Write:
                flags = Flags.Write;
                break;

            case FileAccess.ReadWrite:
                flags = Flags.Read | Flags.Write;
                break;
            }

            switch (mode)
            {
            case FileMode.Append:
                flags |= Flags.Append;
                break;

            case FileMode.Create:
                if (attributes == null)
                {
                    flags |= Flags.CreateNew;
                }
                else
                {
                    flags |= Flags.Truncate;
                }
                break;

            case FileMode.CreateNew:
                flags |= Flags.CreateNew;
                break;

            case FileMode.Open:
                break;

            case FileMode.OpenOrCreate:
                flags |= Flags.CreateNewOrOpen;
                break;

            case FileMode.Truncate:
                flags |= Flags.Truncate;
                break;
            }

            _session = session;

            _handle = _session.RequestOpen(path, flags);

            _attributes = attributes ?? _session.RequestFStat(_handle);

            this.optimalReadRequestSize = checked ((int)this._session.CalculateOptimalReadLength(uint.MaxValue));
            this.readBuffer             = new byte[this.optimalReadRequestSize];
            this.readBufferCount        = 0;

            WRITE_BUFFER_SIZE = (int)_session.CalculateOptimalWriteLength(65536, _handle);

            if (access.HasFlag(FileAccess.Write))
            {
                _writeBuffer = new byte[WRITE_BUFFER_SIZE];
                _writeMode   = true;
            }

            _position = mode != FileMode.Append ? 0 : _attributes.Size;
        }