I have a task to create windows form with functionality to create an XML file of hierarchy of files and folders. I actually managed to do it, but have some trouble. Here is my code:
public static XElement xmlTreeView(DirectoryInfo dir)
{
XDocument xmlDocument = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XComment("Create an XML file containing complete hierarchy of files and folders for a specified folder"));
var info = new XElement("Directory", new XAttribute("name", dir.Name));
foreach (var subDir in dir.GetDirectories())
{
info.Add(new XElement("SubDirectory", new XAttribute("name", subDir.Name),
new XElement("FilesInFolder", subDir.GetFiles().Length)));
foreach (var file in subDir.GetFiles())
{
info.Add(new XElement("File", new XAttribute("name", file.Name),
new XElement("Size", file.Length),
new XElement("CreationTime", file.CreationTime),
new XElement("LastAccess", file.LastAccessTime),
new XElement("LastModified", file.LastWriteTime)));
}
}
foreach (var file in dir.GetFiles())
{
info.Add(new XElement("File", new XAttribute("name", file.Name),
new XElement("Size", file.Length),
new XElement("CreationTime", file.CreationTime),
new XElement("LastAccess", file.LastAccessTime),
new XElement("LastModified", file.LastWriteTime)));
}
return info;
}
the problem is that each folder must have the size and how many files are located in the folder...I tried to calculate the size of the folder, but I couldn't. I was able to show how many files have in subfolder, but all of these files are not shown inside XElement "SubDirectory". If I remove second foreach in subdir, than files not even shown. Help please.
The following program will build an XML tree out of a base directory:
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(string[] args)
{
ConvertToXml(@"C:\test");
}
private static void ConvertToXml(string baseDirectory)
{
var root = new XElement("Root");
var queue = new Queue<KeyValuePair<XElement, string>>();
queue.Enqueue(new KeyValuePair<XElement, string>(root, baseDirectory));
while (queue.Any())
{
var pair = queue.Dequeue();
var path = pair.Value;
var element = pair.Key;
var directories = Directory.GetDirectories(path);
var files = Directory.GetFiles(path);
element.Add(
new XAttribute("Files", files.Length.ToString()),
new XAttribute("Directories", directories.Length.ToString()));
foreach (var directory in directories)
{
var directoryInfo = new DirectoryInfo(directory);
var directoryElement = new XElement("Directory",
new XAttribute("Name", directoryInfo.Name),
new XAttribute("Size", GetDirectorySize(directory)));
element.Add(directoryElement);
queue.Enqueue(new KeyValuePair<XElement, string>(directoryElement, directory));
}
foreach (var file in files)
{
var fileInfo = new FileInfo(file);
var fileElement = new XElement("File",
new XAttribute("Name", fileInfo.Name),
new XAttribute("Size", fileInfo.Length));
element.Add(fileElement);
}
}
var xml = root.ToString();
}
private static long GetDirectorySize(string path)
{
long length = 0;
var queue = new Queue<string>(new[] {path});
while (queue.Any())
{
var value = queue.Dequeue();
var files = Directory.GetFiles(value);
length += files.Sum(s => new FileInfo(s).Length);
var directories = Directory.GetDirectories(value);
foreach (var directory in directories)
queue.Enqueue(directory);
}
return length;
}
}
}
Result:
<Root Files="0" Directories="1">
<Directory Name="root" Size="444" Files="1" Directories="2">
<Directory Name="folder1" Size="148" Files="1" Directories="0">
<File Name="document1.txt" Size="148" />
</Directory>
<Directory Name="folder2" Size="185" Files="1" Directories="0">
<File Name="document2.txt" Size="185" />
</Directory>
<File Name="readme.txt" Size="111" />
</Directory>
</Root>
Notes: