Read all files in directories

May 12, 2010 at 2:35 PM
Edited May 12, 2010 at 2:36 PM
I want to read all files in a folder and all its subfolders and it worked fine in XNA but now I want to do this in silverlight. In XNA I used dictionaries to hold all textures, sounds, and fonts and then retrieved them by using a string as the key for retrieving the data. So I used the direcoryInfo to get the working directory like this.:

string directory = System.Reflection.Assembly.GetExecutingAssembly().Location;
directory = directory.Substring(0, directory.LastIndexOf(("\\")));
DirectoryInfo mDirectoryInfo = new DirectoryInfo(directory + "\\Content\\Images");
FileInfo[] mFileInfoArray = mDirectoryInfo.GetFiles("*.xnb", SearchOption.AllDirectories);

but how do i do the same thing in silverlight. I got the content folder with the image folder and subfolders included in the project. But since I havent found a way of doing this (I hope this can be done in an easy way) and I hope that someone can tell me how to do.
Coordinator
May 12, 2010 at 11:09 PM

This is something I'd like to support and actually had some code in there for it, but it had issues with non-US cultures. I'm looking to get these issues resolved and get this support working again.

May 13, 2010 at 8:21 AM

That would be great. Is there a way to read all files in a given directory for now (without minding the subfolders and their files)?

 

Coordinator
May 13, 2010 at 11:23 AM

You can look at the code in Manifest\Discovery.cs, specifically the GetResourcesInternal method. This is the code that is supposed to enumerate all of the files but it wasn't working properly so it's not currently being called.

May 13, 2010 at 5:52 PM

As I understand with the GetResourceInternal method it retrieves the things that has been given the "resource" property (it also gets a whole lot of other things and I really dont understand what it is). The only thing I had was a couple of .txt-files that was marked as "resource" and i sorted them out by checking the string ending and it worked. But the images, fonts and sounds are marked as "content" so how to do with them? Since the images can be loaded with their names I guess that the information must be somewhere but it might be that the information cannot be extracted.

Coordinator
May 14, 2010 at 1:18 AM

Getting content is tricker, you need to unzip the XAP file and get the names. The only way I could figure out how to do this is asynchronous and you can look at the GetContentInternal method of that same class for code on how to do this.

May 14, 2010 at 10:08 AM

Fantastic! I used the GetContentInternal and by pulling some strings it worked fine :)
Since I had the content ordered in a good folder structure I could check which folder the current content was in with this line:

path.Contains("/Images/")

So with that I got all images in that folder and its subfolders. Here is the code I used:

        private static Dictionary<String, Texture2D> mTextureDictionary = new Dictionary<string, Texture2D>();
        static ContentManager mContentManager;

        static void GetContentInternal()
        {
            string xapFile = Application.Current.Host.Source.LocalPath;
            int idx = xapFile.LastIndexOf("/");
            xapFile = xapFile.Substring(idx + 1);
            WebClient wc = new WebClient();
            wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
            wc.OpenReadAsync(new Uri(xapFile, UriKind.Relative));
        }

        static void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            Stream s = e.Result;
            Unzipper unzip = new Unzipper(s);

            foreach (string path in unzip.GetFileNamesInZip())
            {
                if (path.Contains("/Images/"))
                {
                    string loadPath = path.Remove(0, 8);
                    int pathCutoffIndex = loadPath.LastIndexOf(".");
                    loadPath = loadPath.Substring(0, pathCutoffIndex);
                    pathCutoffIndex = loadPath.LastIndexOf("/");
                    string fileName = loadPath.Remove(0, pathCutoffIndex + 1);
                    content.Add(loadPath);
                    mTextureDictionary.Add(fileName, mContentManager.Load<Texture2D>(loadPath));
                }
            }
        }

So thanks again Bill! Now when I know this I can make a nice separation of the content and load it in as I want and as I see it the problem is solved.

As I am new to silverlight I need to ask a bit more about content :)
Will the client download the content each time he will play the game or is it just the first time he plays the game? My game has pretty much content so it would be nice if the content could be saved somewhere.
And what is the client bin and what can it be used for?

 

Coordinator
May 14, 2010 at 12:29 PM

Ok great. For now, all content and resources are in the XAP file (basically a ZIP file that contains the binaries + content) and this is cached using the browser cache. So unless the XAP file changes it should be retrieved from browser cache. We are considering adding support for getting content from an external XAP file or loose files on the server, but nothing is scheduled at this point.