Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

File.WriteAllBytes - Sharing Violation on Path

Discussion in 'Scripting' started by wshigham, Sep 4, 2020.

  1. wshigham

    wshigham

    Joined:
    Dec 30, 2019
    Posts:
    14
    Hi all,

    I have written a script to render a picture of each prefab in my Assets\Prefabs folder and save the Texture2D as a .png file to an Assets\Icons folder.

    Idea being that I don't need to spend time making icons as they are just generated from the models. (I am aware of AssetPreview.GetAssetPreview but want to be able to control the angle that the preview is taken from for the icon).

    If the icons in my folder don't already exist, my script works fine. But if they do already exist, there seems to be a problem: IOException: Sharing violation on path C:\....
    I.e. the issue seems to be with overwriting existing files.

    I am simply doing the below, in a loop.

    Code (CSharp):
    1. // Encode texture into PNG
    2. byte[] bytes = texTransparent.EncodeToPNG();
    3.  
    4. // Write the icon png to the disk  
    5. File.WriteAllBytes(Application.dataPath + "/Icons/Items/" + fName + ".png", bytes);
    This code is inside an IEnumerator which is called from a custom toolbar command.

    Any help is much appreciated.
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,722
    If i were you i would just do something like
    Code (CSharp):
    1. if (File.Exists(path)) {
    2.   File.Delete(path):
    3. }
    4.  
    5. // Then your original code
     
  3. wshigham

    wshigham

    Joined:
    Dec 30, 2019
    Posts:
    14
    Thanks, so I tried that. Interestingly it deletes the first file (and then creates it successfully), but then has a file violation on the second file.

    This made me realise the issue is to do with how quickly it is looping to the next file - the first file is still being written. I added
    Code (CSharp):
    1. yield return new EditorWaitForSeconds(2f);
    after each loop and it now works fine (albeit more slowly!) I don't really understand why the issue didn't occur when the files didn't already exist. Perhaps overwriting a file is slower.

    I don't particularly like the solution to just add a 2 second wait, is there a method to detect if the file system is busy, and then carry on when it is ready? I suppose I could do a while loop, with a try/catch but it doesn't feel great.
     
  4. wshigham

    wshigham

    Joined:
    Dec 30, 2019
    Posts:
    14
    I have solved my issue using the below code, but I don't particularly like it and if someone knows a better way to detect if the file system is busy I'd appreciate it.

    Code (CSharp):
    1. // Define a maximum number of attempts
    2.             int numAttempts = 0;
    3.             int maxAttempts = 100;
    4.             while(!madeFile)
    5.             {
    6.                 try
    7.                 {
    8.                     File.WriteAllBytes(filePath, bytes);
    9.                     madeFile = true;
    10.                 }
    11.                 catch (Exception)
    12.                 {
    13.                     numAttempts++;                  
    14.                     if (numAttempts > maxAttempts)
    15.                     {
    16.                         madeFile = true;
    17.                         Debug.Log("Could not make file " + fName);
    18.                     }
    19.                 }
    20.                 // Add a small delay to allow the file system to no longer be busy
    21.                 yield return new EditorWaitForSeconds(0.1f);
    22.             }
     
  5. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,531
    PraetorBlue and wshigham like this.
  6. wshigham

    wshigham

    Joined:
    Dec 30, 2019
    Posts:
    14
    Thanks, added that into my code.
     
  7. RockStar89

    RockStar89

    Joined:
    May 6, 2018
    Posts:
    3
    Thank you for this - This just helped me, appreciate it. Was running up thousands of errors in the console using File.WriteAllBytes while saving a byte[] that gets played as a video. Couldn't figure out what was wrong, just had to check if the file path existed first, this helped, shout out to you. Take care