/// <summary> /// Get file data of a specified remote file in FlashAir card and save it in local folder. /// </summary> /// <param name="remoteFilePath">Remote file path</param> /// <param name="localFilePath">Local file path</param> /// <param name="size">File size provided by FlashAir card</param> /// <param name="itemDate">Date provided by FlashAir card</param> /// <param name="canReadExif">Whether can read Exif metadata from the file</param> /// <param name="progress">Progress</param> /// <param name="token">CancellationToken</param> /// <param name="card">FlashAir card information</param> /// <returns>Byte array of the file</returns> internal static async Task <byte[]> GetSaveFileAsync(string remoteFilePath, string localFilePath, int size, DateTime itemDate, bool canReadExif, IProgress <ProgressInfo> progress, CancellationToken token, CardInfo card) { if (String.IsNullOrWhiteSpace(remoteFilePath)) { throw new ArgumentNullException("remoteFilePath"); } if (String.IsNullOrWhiteSpace(localFilePath)) { throw new ArgumentNullException("localFilePath"); } var remotePath = ComposeRemotePath(FileManagerCommand.None, remoteFilePath); try { using (var client = new HttpClient() { Timeout = timeoutLength }) { var bytes = await DownloadBytesAsync(client, remotePath, size, progress, token, card).ConfigureAwait(false); using (var fs = new FileStream(localFilePath, FileMode.Create, FileAccess.Write)) { await fs.WriteAsync(bytes, 0, bytes.Length, token).ConfigureAwait(false); } // Conform date of copied file in local folder to that of original file in FlashAir card. var localFileInfo = new FileInfo(localFilePath); localFileInfo.CreationTime = itemDate; // Creation time localFileInfo.LastWriteTime = itemDate; // Last write time // Overwrite creation time of copied file by date of image taken from Exif metadata. if (canReadExif) { var exifDateTaken = await ImageManager.GetExifDateTakenAsync(bytes); if (exifDateTaken != DateTime.MinValue) { localFileInfo.CreationTime = exifDateTaken; } } return(bytes); } } catch { Debug.WriteLine("Failed to get and save a file."); throw; } }
/// <summary> /// Gets file data of a specified remote file in FlashAir card and save it in local folder. /// </summary> /// <param name="client">HttpClient</param> /// <param name="remoteFilePath">Remote file path</param> /// <param name="localFilePath">Local file path</param> /// <param name="size">File size provided by FlashAir card</param> /// <param name="itemDate">Date provided by FlashAir card</param> /// <param name="canReadExif">Whether can read Exif metadata from the file</param> /// <param name="progress">Progress</param> /// <param name="card">FlashAir card information</param> /// <param name="cancellationToken">CancellationToken</param> /// <returns>Byte array of file</returns> internal static async Task <byte[]> GetSaveFileAsync(HttpClient client, string remoteFilePath, string localFilePath, int size, DateTime itemDate, bool canReadExif, IProgress <ProgressInfo> progress, CardInfo card, CancellationToken cancellationToken) { if (string.IsNullOrWhiteSpace(remoteFilePath)) { throw new ArgumentNullException(nameof(remoteFilePath)); } if (string.IsNullOrWhiteSpace(localFilePath)) { throw new ArgumentNullException(nameof(localFilePath)); } var remotePath = ComposeRemotePath(FileManagerCommand.None, remoteFilePath); byte[] bytes = null; try { bytes = await DownloadBytesAsync(client, remotePath, size, progress, card, cancellationToken).ConfigureAwait(false); } catch { Debug.WriteLine("Failed to get a file."); throw; } int retryCount = 0; while (true) { try { using (var fs = new FileStream(localFilePath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) { var creationTime = itemDate; var lastWriteTime = itemDate; // Overwrite creation time by date of image taken from Exif metadata. if (canReadExif) { var exifDateTaken = await ImageManager.GetExifDateTakenAsync(bytes, DateTimeKind.Local); if (exifDateTaken != default(DateTime)) { creationTime = exifDateTaken; } } FileTime.SetFileTime(fs.SafeFileHandle, creationTime: creationTime, lastWriteTime: lastWriteTime); await fs.WriteAsync(bytes, 0, bytes.Length, cancellationToken).ConfigureAwait(false); } return(bytes); } catch (IOException) when(++retryCount < MaxRetryCount) { // Wait interval before retry. if (TimeSpan.Zero < _retryInterval) { await Task.Delay(_retryInterval, cancellationToken); } } catch { Debug.WriteLine("Failed to save a file."); throw; } } }