2017-12-01 3 views
1

FTP에서 Azure File Storage로 파일을 전송해야합니다. 내 코드는 정상적으로 작동하지만 모범 사례가 아닌 메모리에서 파일을 전송합니다. 먼저 메모리에있는 Byte 배열로 스트림을 읽습니다. 그런 다음 출력을 Azure 파일 저장소에 업로드합니다.로컬에서 메모리 또는 디스크를 유지하지 않고 FTP에서 Azure File Storage로 파일을 직접 전송하십시오.

이제 비동기 적으로 처리하는 것이 좋습니다. 그러나 이것이 가능하고 어떻게 할 수 있는지 나는 모른다.

내 코드 : 내가 제대로 이해하면

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using Microsoft.WindowsAzure.Storage; 
using System.Configuration; 
using Microsoft.WindowsAzure.Storage.File; 
using System.IO; 
using Microsoft.Azure; 
using System.Net; 

namespace TransferFtpToAzure 
{ 
    class Program 
    { 
     public static void Main(string[] args) 
     { 
      List<FileName> sourceFileList = new List<FileName>(); 
      List<FileName> targetFileList = new List<FileName>(); 

      string targetShareReference = ConfigurationManager.AppSettings["AzureShare"]; 
      string targetDirectoryReference = ConfigurationManager.AppSettings["Environment"] + "/" + Enums.AzureFolders.Mos + "/" + Enums.AzureFolders.In; 
      string sourceURI = (ConfigurationManager.AppSettings["FtpConnectionString"] + ConfigurationManager.AppSettings["Environment"].ToUpper() +"/"+ Enums.FtpFolders.Mos + "/").Replace("\\","/"); 
      string sourceUser = ConfigurationManager.AppSettings["FtpServerUserName"]; 
      string sourcePass = ConfigurationManager.AppSettings["FtpServerPassword"]; 

      getFileLists(sourceURI, sourceUser, sourcePass, sourceFileList, targetShareReference, targetDirectoryReference, targetFileList); 

      Console.WriteLine(sourceFileList.Count + " files found!"); 

      CheckLists(sourceFileList, targetFileList); 
      targetFileList.Sort(); 

      Console.WriteLine(sourceFileList.Count + " unique files on sourceURI" + Environment.NewLine + "Attempting to move them."); 

      foreach (var file in sourceFileList) 
      { 
       try 
       { 
        CopyFile(file.fName, sourceURI, sourceUser, sourcePass, targetShareReference, targetDirectoryReference); 
       } 
       catch 
       { 
        Console.WriteLine("There was move error with : " + file.fName); 
       } 
      } 
     } 

     public class FileName : IComparable<FileName> 
     { 
      public string fName { get; set; } 
      public int CompareTo(FileName other) 
      { 
       return fName.CompareTo(other.fName); 
      } 
     } 

     public static void CheckLists(List<FileName> sourceFileList, List<FileName> targetFileList) 
     { 
      for (int i = 0; i < sourceFileList.Count; i++) 
      { 
       if (targetFileList.BinarySearch(sourceFileList[i]) > 0) 
       { 
        sourceFileList.RemoveAt(i); 
        i--; 
       } 
      } 
     } 

     public static void getFileLists(string sourceURI, string sourceUser, string sourcePass, List<FileName> sourceFileList, string targetShareReference, string targetDirectoryReference, List<FileName> targetFileList) 
     { 
      string line = ""; 
      /////////Source FileList 
      FtpWebRequest sourceRequest; 
      sourceRequest = (FtpWebRequest)WebRequest.Create(sourceURI); 
      sourceRequest.Credentials = new NetworkCredential(sourceUser, sourcePass); 
      sourceRequest.Method = WebRequestMethods.Ftp.ListDirectory; 
      sourceRequest.UseBinary = true; 
      sourceRequest.KeepAlive = false; 
      sourceRequest.Timeout = -1; 
      sourceRequest.UsePassive = true; 
      FtpWebResponse sourceRespone = (FtpWebResponse)sourceRequest.GetResponse(); 
      //Creates a list(fileList) of the file names 
      using (Stream responseStream = sourceRespone.GetResponseStream()) 
      { 
       using (StreamReader reader = new StreamReader(responseStream)) 
       { 
        line = reader.ReadLine(); 
        while (line != null) 
        { 
         var fileName = new FileName 
         { 
          fName = line 
         }; 
         sourceFileList.Add(fileName); 
         line = reader.ReadLine(); 
        } 
       } 
      } 
      /////////////Target FileList 
      CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString")); 
      CloudFileClient fileClient = storageAccount.CreateCloudFileClient(); 
      //var test = fileClient.ListShares(); 
      CloudFileShare fileShare = fileClient.GetShareReference(targetShareReference); 
      if (fileShare.Exists()) 
      { 
       CloudFileDirectory rootDirectory = fileShare.GetRootDirectoryReference(); 
       if (rootDirectory.Exists()) 
       { 
        CloudFileDirectory customDirectory = rootDirectory.GetDirectoryReference(targetDirectoryReference); 
        if (customDirectory.Exists()) 
        { 
         var fileCollection = customDirectory.ListFilesAndDirectories().OfType<CloudFile>(); 
         foreach (var item in fileCollection) 
         { 
          var fileName = new FileName 
          { 
           fName = item.Name 
          }; 
          targetFileList.Add(fileName); 
         } 
        } 
       } 
      } 
     } 

     public static void CopyFile(string fileName, string sourceURI, string sourceUser, string sourcePass, string targetShareReference, string targetDirectoryReference) 
     { 
      try 
      { 
       FtpWebRequest request = (FtpWebRequest)WebRequest.Create(sourceURI + fileName); 
       request.Method = WebRequestMethods.Ftp.DownloadFile; 
       request.Credentials = new NetworkCredential(sourceUser, sourcePass); 
       FtpWebResponse response = (FtpWebResponse)request.GetResponse(); 
       Stream responseStream = response.GetResponseStream(); 
       Upload(fileName, ToByteArray(responseStream), targetShareReference, targetDirectoryReference); 
       responseStream.Close(); 
      } 
      catch 
      { 
       Console.WriteLine("There was an error with :" + fileName); 
      } 
     } 

     public static Byte[] ToByteArray(Stream stream) 
     { 
      MemoryStream ms = new MemoryStream(); 
      byte[] chunk = new byte[4096]; 
      int bytesRead; 
      while ((bytesRead = stream.Read(chunk, 0, chunk.Length)) > 0) 
      { 
       ms.Write(chunk, 0, bytesRead); 
      } 

      return ms.ToArray(); 
     } 

     public static bool Upload(string FileName, byte[] Image, string targetShareReference, string targetDirectoryReference) 
     { 
      try 
      { 
       CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString")); 
       CloudFileClient fileClient = storageAccount.CreateCloudFileClient(); 
       //var test = fileClient.ListShares(); 
       CloudFileShare fileShare = fileClient.GetShareReference(targetShareReference); 
       if (fileShare.Exists()) 
       { 
        CloudFileDirectory rootDirectory = fileShare.GetRootDirectoryReference(); 
        if (rootDirectory.Exists()) 
        { 
         CloudFileDirectory customDirectory = rootDirectory.GetDirectoryReference(targetDirectoryReference); 
         if (customDirectory.Exists()) 
         { 
          var cloudFile = customDirectory.GetFileReference(FileName); 
          using (var stream = new MemoryStream(Image, writable: false)) 
          { 
           cloudFile.UploadFromStream(stream); 
          } 
         } 
        } 
       } 
       return true; 
      } 
      catch 
      { 
       return false; 
      } 
     } 
    } 
} 

답변

1

, 당신은 다운로드 및 업로드 사이의 메모리에 파일을 stoing 피하려고.

FtpWebRequest request = (FtpWebRequest)WebRequest.Create(sourceURI + fileName); 
request.Method = WebRequestMethods.Ftp.DownloadFile; 
request.Credentials = new NetworkCredential(sourceUser, sourcePass); 
FtpWebResponse response = (FtpWebResponse)request.GetResponse(); 
using (Stream responseStream = response.GetResponseStream()) 
{ 
    cloudFile.UploadFromStream(responseStream); 
} 
+0

을 사실, 그게 내가 피하고 싶은 것입니다 :

당신은 CloudFile.UploadFromStream에 직접 FtpWebResponse.GetResponseStream 스트림을 전달하여 그렇게 할 수 있습니다. 비동기 메서드로 작업해야한다고 생각했습니다 :). 고맙습니다!! – hatsjie

관련 문제