2011-12-24 4 views
2

私はそうのようなディレクトリ作成しています作成されたディレクトリにファイルを保存することはできません。上記のディレクトリが作成された後ビットマップだけで、プログラム

Directory.CreateDirectory(context.Server.MapPath(String.Format("Uploads/{0}/Main", currentUploadDir + 1))); 

を、私は、画像を保存するためにBitmap.Saveメソッドを使用しようとしますそのようなそのディレクトリに:

bitmap.Save(outFile, jpgEncoder, ep); 

保存する上記の方法が失敗し、私は次の例外を提示しています:

An exception of type 'System.Runtime.InteropServices.ExternalException' occurred in System.Drawing.dll but was not handled in user code 

Additional information: A generic error occurred in GDI+. 

Windowsエクスプローラで同じディレクトリを(同じパスに)手動で作成すると、Bitmap.Saveメソッドは問題なくイメージを作成できます。

最初は、これは権限の問題である可能性があります。しかし、両方の場合(プログラムまたは手動でディレクトリを作成する場合)、正しいパーミッションは親ディレクトリから継承されています。だから、私はこれが問題であると見ることができます。

誰もがこの例外の原因を知っていますか?

これは、私は上記の記述しています問題に苦しんでいるHTTPハンドラのコードです:

public class FileUpload : IHttpHandler, IRequiresSessionState 
{ 
    private static ImageCodecInfo jpgEncoder; 

    public void ProcessRequest(HttpContext context) 
    { 
     if (context.Request.Files.Count > 0) 
     { 
      int providerId = 0; 
      int employeeId = 0; 

      int chunk = context.Request["chunk"] != null ? int.Parse(context.Request["chunk"]) : 0; 
      int chunks = context.Request["chunks"] != null ? int.Parse(context.Request["chunks"]) : 0; 

      int currentUploadDir = 0; 

      if (chunk == 0) 
      { 
       currentUploadDir = GetCurrentActiveUploadDirectory(context); 
       context.Session["CurrentUploadDir"] = currentUploadDir; 
      } 
      else 
      { 
       currentUploadDir = Convert.ToInt32(context.Session["CurrentUploadDir"]); 
      } 

      string mainImgPath = String.Format("Uploads/{0}/Main", currentUploadDir); 
      string thumbImgPath = String.Format("Uploads/{0}/Thumb", currentUploadDir); 
      string mobileImgPath = String.Format("Uploads/{0}/Mobile", currentUploadDir); 

      // Get the provider id. 
      if (!String.IsNullOrEmpty(context.Request.QueryString["ProviderId"])) 
      { 
       providerId = Convert.ToInt32(context.Request.QueryString["ProviderId"]); 
      } 
      else 
      { 
       return; 
      } 

      // Get the employee id. 
      if (!String.IsNullOrEmpty(context.Request.QueryString["EmployeeId"])) 
      { 
       employeeId = Convert.ToInt32(context.Request.QueryString["EmployeeId"]); 
      } 
      else 
      { 
       return; 
      } 

      // If we already have 7 images for this provider, we will silently fail to add any more images. 
      if (Company.GetFileCount(providerId) < 7) 
      { 
       string fileName = String.Empty; 

       if (chunk == 0) 
       { 
        Company company = Company.GetCompany(providerId); 

        File file = File.NewFile(); 
        file.FileCategory = "Facility Photo"; 
        file.Featured = 0; 
        file.Cover = 0; 
        file.Status = "A"; 
        file.FileUrl = mainImgPath; 
        file.ProviderId = providerId; 
        file.EmployeeId = employeeId; 
        file = file.Save(); 

        fileName = context.Request["name"] != null ? context.Request["name"] : string.Empty;      

        // Create SEO friendly name to images [space-city-state-number] 
        // Space = Provider Id. 
        // City = City (DB field). 
        // State = State (DB field). 
        // Number = Incremental value for each image (i.e. 1, 2, 3, ...). 
        fileName = String.Concat(company.BranchDept.Replace(' ', '_'), "-", 
               String.IsNullOrEmpty(company.City) ? String.Empty : String.Concat(company.City.Replace(' ', '_'), "-"), 
               String.IsNullOrEmpty(company.State) ? String.Empty : String.Concat(company.State.Replace(' ', '_'), "-"), 
               file.Id, 
               fileName.Substring(fileName.LastIndexOf('.'), fileName.Length - fileName.LastIndexOf('.'))); 

        file.FileName = fileName; 
        file.FileDescription = fileName; 
        file.FileType = context.Request.Files[0].ContentType; 
        file.Save(); 

        context.Session["UploadFileName"] = fileName; 
       } 
       else 
       { 
        fileName = context.Session["UploadFileName"].ToString(); 
       } 

       HttpPostedFile fileUpload = context.Request.Files[0]; 

       // Create and save the main image. 
       using (var fs = new FileStream(Path.Combine(context.Server.MapPath(mainImgPath), fileName), chunk == 0 ? FileMode.Create : FileMode.Append)) 
       { 
        var buffer = new byte[fileUpload.InputStream.Length]; 
        fileUpload.InputStream.Read(buffer, 0, buffer.Length); 
        fs.Write(buffer, 0, buffer.Length); 
       } 

       // We will only create the thumbnail and mobile images if this is the last chunk of the main image. 
       if ((chunk + 1) == chunks) 
       { 
        // Create, resize and save the thumbnail image. 
        ResizeImage(Path.Combine(context.Server.MapPath(mainImgPath), fileName), 45, Path.Combine(context.Server.MapPath(thumbImgPath), fileName)); 

        // Create, resize and save the mobile image. 
        ResizeImage(Path.Combine(context.Server.MapPath(mainImgPath), fileName), 10, Path.Combine(context.Server.MapPath(mobileImgPath), fileName)); 
       } 
      } 
     } 
    } 

    /// <summary> 
    /// Determines what the current upload directory is and if a new one needs to be created. 
    /// </summary> 
    /// <param name="context">Http context object.</param> 
    /// <returns>Integer value representing the current upload directoy.</returns> 
    private static int GetCurrentActiveUploadDirectory(HttpContext context) 
    { 
     // Get the current active directory for file upload. 
     DirectoryInfo uploadsDir = new DirectoryInfo(context.Server.MapPath("Uploads")); 
     DirectoryInfo[] subDirectories = uploadsDir.GetDirectories(); 

     List<int> subDirNames = new List<int>(); 

     foreach (DirectoryInfo dir in subDirectories) 
     { 
      if (Utilities.IsNumeric(dir.Name, System.Globalization.NumberStyles.Integer)) 
      { 
       subDirNames.Add(Convert.ToInt32(dir.Name)); 
      } 
     } 

     subDirNames.Sort(); 

     int currentUploadDir = subDirNames[subDirNames.Count - 1]; 

     // Get the count of files in the current active upload directory. 
     int fileCount = Directory.GetFiles(context.Server.MapPath(String.Format("Uploads/{0}", currentUploadDir)), "*.*", SearchOption.AllDirectories).Length; 

     // Determine if a new active upload directory needs to be created. 
     if (fileCount > 25) // 7000 in each one of the 3 subdirectories (Main, Thumb, Mobile). 
     { 
      // Create a new active directory structure. 
      //uploadsDir.CreateSubdirectory(String.Format("{0}/Main", currentUploadDir + 1)); 
      //uploadsDir.CreateSubdirectory(String.Format("{0}/Thumbnail", currentUploadDir + 1)); 
      //uploadsDir.CreateSubdirectory(String.Format("{0}/Mobile", currentUploadDir + 1)); 

      Directory.CreateDirectory(context.Server.MapPath(String.Format("Uploads/{0}/Main", currentUploadDir + 1))); 
      Directory.CreateDirectory(context.Server.MapPath(String.Format("Uploads/{0}/Thumbnail", currentUploadDir + 1))); 
      Directory.CreateDirectory(context.Server.MapPath(String.Format("Uploads/{0}/Mobile", currentUploadDir + 1))); 

      currentUploadDir++; 
     } 

     return currentUploadDir; 
    } 

    /// <summary> 
    /// Resizes and saves the specified image. 
    /// </summary> 
    /// <param name="inFile">The file path of the image to be resized.</param> 
    /// <param name="maxDimension">The max height or width that the image will be resized to.</param> 
    /// <param name="outFile">The file path of the resized image.</param> 
    private void ResizeImage(string inFile, int maxDimension, string outFile) 
    { 
     using (Stream stream = new FileStream(inFile, FileMode.Open)) 
     { 
      using (Image inImage = Image.FromStream(stream)) 
      { 
       double width; 
       double height; 
       if (inImage.Height < inImage.Width) 
       { 
        width = maxDimension; 
        height = (maxDimension/(double)inImage.Width) * inImage.Height; 
       } 
       else 
       { 
        height = maxDimension; 
        width = (maxDimension/(double)inImage.Height) * inImage.Width; 
       } 
       using (Bitmap bitmap = new Bitmap((int)width, (int)height)) 
       { 
        using (Graphics graphics = Graphics.FromImage(bitmap)) 
        { 
         graphics.SmoothingMode = SmoothingMode.HighQuality; 
         graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; 
         graphics.DrawImage(inImage, 0, 0, bitmap.Width, bitmap.Height); 

         if (inImage.RawFormat.Guid == ImageFormat.Jpeg.Guid) 
         { 
          if (jpgEncoder == null) 
          { 
           ImageCodecInfo[] ici = ImageCodecInfo.GetImageDecoders(); 

           foreach (ImageCodecInfo info in ici) 
           { 
            if (info.FormatID == ImageFormat.Jpeg.Guid) 
            { 
             jpgEncoder = info; 
             break; 
            } 
           } 
          } 

          if (jpgEncoder != null) 
          { 
           EncoderParameters ep = new EncoderParameters(1); 
           //A quality level of 0 corresponds to the greatest compression, and a quality level of 100 corresponds to the least compression. 
           ep.Param[0] = new EncoderParameter(Encoder.Quality, 100L); 
           bitmap.Save(outFile, jpgEncoder, ep); 
          } 
          else 
          { 
           bitmap.Save(outFile, inImage.RawFormat); 
          } 
         } 
         else 
         { 
          // Fill with white for transparent GIFs 
          graphics.FillRectangle(Brushes.White, 0, 0, bitmap.Width, bitmap.Height); 
          bitmap.Save(outFile, inImage.RawFormat); 
         } 
        } 
       } 
      } 
     } 
    } 

    public bool IsReusable 
    { 
     get 
     { 
      return false; 
     } 
    } 
} 
+0

作成したディレクトリが作成しようとしているものと同じであることを確認するには、ディレクトリ文字列を作成して変数に保存します。それから、両方の機能で使用してください。 –

+0

'outFile'と作成されたフォルダの関係を表示できますか? –

+0

私の質問が参照しているソースコードを追加しました。 – bbeny

答えて

0

は何が起こっているかを見るためのSysinternalsにProcmonツールを使用してみてください「カバーの下に。」

0

Microsoft documentationには、ビットマップを保存するときにExternalExceptionが発生する理由がいくつかあります。 (これらを排除しましたか?)

+0

これらの理由を確認しました。しかし、マイクロソフトの説明から、私はそれらのどれもが私の問題の原因だとは思っていません。マイクロソフトでは、画像が間違った画像フォーマットで保存されている可能性があると主張しています(私は間違いないと確信しています)。または、イメージが作成されたのと同じファイルに保存されました(どちらもそうは思いません)。 – bbeny

+0

そして、Procmonを使って何が起きているのかを見てみましょう。 – jdigital

+0

Procmonを使ってみましたが、intrestの何も表示されませんでした。画像を書いているフォルダには多くのIOアクティビティがありましたが、例外的なことは何もありません。 – bbeny

関連する問題