Skip to main content
gamedev.net
🔒 Locked

[.net] (solved) C# -- NullReference Exception when returning array...

Started by taby Jan 25, 2006 at 2:17 PM 2 replies 2.3k views
Original Post
taby
taby
Hello, I have written the necessary code to dump a file system listing to an XML file. However, I am trying to return arrays from the fs2xml::entry_point::get_*_list functions, but I am suspicious that I am not returning them correctly. Is there something plainly obvious that I am missing? :) Any help would be greatly appreciated! Thanks.

using System;
using System.IO; // console.writeline, file system enumeration, etc.
using System.Text; // encoding.utf8
using System.Xml; // xmltextwriter

namespace fs2xml
{
	class entry_point
	{
		// XML document object for writing out enumerated file system info
		static protected XmlTextWriter xml_writer;

		[STAThread]
		static int Main(string[] args)
		{
			// check to see we have a directory name, and an output XML file name
			if(2 != args.Length)
			{
				Console.WriteLine("Usage:"); 
				Console.WriteLine("  fs2xml directory_name output_xml_file_name"); 
				return -1;
			}

			// scratch variables
			String dir_name = args[0];
			String xml_file = args[1];
	
			// test that initial directory even exists
			if(false == Directory.Exists(dir_name))
			{
				Console.WriteLine("Error: " + dir_name + " does not exist.");
				return -2;
			}

			// create the XML document, start with a root element of "listing"
			xml_writer = new XmlTextWriter(xml_file, Encoding.UTF8);
			xml_writer.WriteStartDocument();
			xml_writer.WriteStartElement("listing");

			// recursively dump file and subdir listing to xml file
			dir_list_to_xml(dir_name);

			// cleanup
			xml_writer.WriteEndElement();
			xml_writer.WriteEndDocument();
			xml_writer.Close();

			return 0;
		}

		// list files in current directory, as well as subdirectories and their contents
		static void dir_list_to_xml(String dir_name)
		{
			// sanity check / ease of use later down the road in concatenation ops
			if('\\' != dir_name[dir_name.Length - 1])
				dir_name += '\\';

			// list the files
			fs_item_info[] file_list = get_file_list(dir_name);

			for(int i = 0; i < file_list.Length; i++)
			{
				xml_writer.WriteStartElement("file");
				xml_writer.WriteElementString("name", file_list.name);
				xml_writer.WriteElementString("last_mod", file_list.last_modified.ToString());
				xml_writer.WriteEndElement();
			}

			// list the subdirs
			fs_item_info[] dir_list = get_sub_dir_list(dir_name);

			// recursively call this same function for each subdir found
			for(int i = 0; i < dir_list.Length; i++)
			{
				xml_writer.WriteStartElement("directory");
				xml_writer.WriteElementString("name", dir_list.name);
				xml_writer.WriteElementString("last_mod", dir_list.last_modified.ToString());

				dir_list_to_xml(dir_name + dir_list.name);

				xml_writer.WriteEndElement();
			}
		}

		// get file info array
		static fs_item_info[] get_file_list(string dir_name)
		{
			DirectoryInfo root_dir = new DirectoryInfo(dir_name);
			FileInfo[] files = root_dir.GetFiles("*.*");

			fs_item_info[] fsi = new fs_item_info[files.Length];

			for(int i = 0; i < files.Length; i++)
			{
				fsi.name = files.Name;
				fsi.last_modified = files.LastWriteTime;
			}

			//return (fs_item_info[])fsi.Clone();
			return fsi; // ?????
		}

		// get subdir info array
		static fs_item_info[] get_sub_dir_list(string dir_name)
		{
			DirectoryInfo root_dir = new DirectoryInfo(dir_name);
			DirectoryInfo[] sub_dirs = root_dir.GetDirectories("*.*");

			fs_item_info[] fsi = new fs_item_info[sub_dirs.Length];

			for(int i = 0; i < sub_dirs.Length; i++)
			{
				fsi.name = sub_dirs.Name;
				fsi.last_modified = sub_dirs.LastWriteTime;
			}

			return fsi;
		}
	}

	// all file/dir info one needs should go in here
	class fs_item_info
	{
		public String name = "";
		public DateTime last_modified = DateTime.MinValue;
	}
}




[Edited by - taby on January 25, 2006 3:18:54 PM]
Enselic
Enselic
When you create arrays of fs_item_info you only create the array, but not the objects.

Replace
			fs_item_info[] fsi = new fs_item_info[files.Length];			for (int i = 0; i < files.Length; i++) {				fsi.name = files.Name;				fsi.last_modified = files.LastWriteTime;			}

with
			fs_item_info[] fsi = new fs_item_info[files.Length];			for (int i = 0; i < files.Length; i++) {				fsi = new fs_item_info();				fsi.name = files.Name;				fsi.last_modified = files.LastWriteTime;			}

on that and all the other places and you will at least get rid of the Null exceptions.

In C#, all classes are reference types, i.e. you can see all class variables as pointers. When you created the arrays, you ended up with an array of null class pointers.

And also, do you have to code C# in C-style? [smile]. I don't know about you, but I find it very irritating reading code that uses two styles. I would greatly advice you use the C# coding conventions, i.e.
class PascalCase{    private float floatMember; // some prefer _floatMember    public void MethodInPascalCase(int parametersInCamel)    {        int localsInCamel;    }}


And finally, I recomend you to use MS Visual C# Express Edtion. It is

  • Free

  • Very good.

  • ...including a great great great debuger which helps you find these kinds of bugs in a few secs (as I did with your code).


I like that such a heavy C/C++ guy tries C# though. Good choice.
taby
taby
Ahh, bravo. Thank you so much! I knew exactly what was Null, just didn't know what was the matter. :)

Thank you very much!!

I'll try to switch my C# style a little... I've done it for VBScript before. :) I actually like camelCase and PascalCase.

Wow, this was only my 2nd C# program, but I'm really liking it so far. I just desperately need to refer to some information about Collections!

I haven't tried the 2005 IDE out yet, but I will eventually migrate.

Hehe VIVE LE C++!!!!!!!!!!!! ;)

Rating++

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.