/// <summary>Download a complete file</summary>
        public static async Task downloadFile(this Connection conn, FileInfo fi, Stream destStream, int bufferSize = defaultBufferSize)
        {
            if (fi.length <= 0)
            {
                return;
            }

            if (bufferSize <= 0)
            {
                bufferSize = defaultBufferSize;
            }
            if (fi.length <= bufferSize)
            {
                bufferSize = (int)fi.length;
            }

            // Open the file
            int fd = (await conn.createFileImpl(fi.id, eFileOpenFlags.None)).fd;

            // Send read request for the complete file. Let's hope their server software is well designed and streams data, instead of trying to read the complete file to RAM first.
            RequestBuilder req = conn.newRequest("file_read");

            req.add("fd", fd);
            req.add("count", fi.length);

            try
            {
                await conn.download(req, destStream, fi.length);
            }
            finally
            {
                // Close the file
                await conn.closeFile(fd);
            }
        }
        /// <summary>Delete a file</summary>
        public static Task deleteFile(this Connection conn, FileInfo fi)
        {
            var req = conn.newRequest("deletefile");

            req.add("fileid", fi.id);
            req.unixTimestamps();

            return(conn.send(req));
        }
 /// <summary>Open an existing file</summary>
 public static Task <FileDescriptor> createFile(this Connection conn, FileInfo fi, FileMode mode, FileAccess access)
 {
     return(conn.createFile(fi.id, mode, access));
 }