電子書籍の厳選無料作品が豊富!

XmlDocument.ReadNode()メソッドについて質問があります。

現在、VisualStudio2003のVisual C#で、XMLファイルを読み込むアプリケーションを作っています。その際、XmlTextReaderで、あるファイルを読み込み、XmlDocument.ReadNode()で要素を読み込もうとすると、「インデックスが配列の境界外です。」というIndexOutOfExceptionが発生します。

読み込もうとしているファイルは約2GBで、ReadNode()で読み込まれる要素の数は約80,0000個です。

ここで質問なのですが、ReadNode()には、扱えるファイルサイズの上限のようなものがあるのでしょうか、それとも読み込める要素の数に上限があるのでしょうか。



プログラム例:

//"input.xml"は、サイズが約2GBで、Elementの数が約80,0000
XmlTextReader reader = new XmlTextReader("input.xml");
reader->MoveToContent();
XmlDocument xml = new XmlDocument();

//ここ↓のWhileを約80,0000回ループすると75,0000回あたり
//でIndexOutOfRangeExceptionがReadNode()からスローされる
while (reader.MoveToNextAttribute())
{
try
{
XmlNode a = doc.ReadNode(reader);
}
catch(Exception e)
{
//ここで「インデックスが配列の境界外です。」をキャッチ
}
}

A 回答 (1件)

検索したところでは


いくつか2GBの制約があるというのを見つけることが出来た。
MS公式情報ではないのでどれだけ信頼性のある情報かわからない。

すくなくともMSDN Library2にはこの件に関する記述はない
http://msdn2.microsoft.com/en-us/library/system. …

http://www.thescripts.com/forum/thread171942.html
http://www.topxml.com/system_xml/system_xml_xmlt …

>Use this class when iterating through or retrieving data from larger documents, and when validation is not required.【However, note that this class does not support files larger than 2GB.】 Below are three simple examples that incorporate the System.Xml.XmlTextReader class.

本当はMSDNあたりからの情報が欲しいんだけどな。

http://www.thescripts.com/forum/thread572092.html

>A process can only use up to 2GB memoery on a 32 bit operating system. In
this case, you cannot load an xml file larger than 2GB into memory using
XmlDocument. In this case, I suggest you use XmlTextReader.【As far as I know, in .NET framework 1.1, it has a 2GB limit also. However, in 2.0 this limit was fixed and no longer exists.】

によれば.NET 2.0ではこの問題は治っているようだ、との記述もあるようだが・・・質問者様が恐らく納品されるであろう先の制限で出来ないんだろうね・・・

この回答への補足

テストで使ったコードです↓
インデントが無茶苦茶ですみません。

ファイル生成:

class Program
{
static void Main(string[] args)
{
UInt64 num = 0;
string filename = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
string path = System.IO.Path.GetDirectoryName(filename);
StreamWriter sw =
new StreamWriter(path + "\\test.xml", true);
sw.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
sw.WriteLine("<root>");
//while (num < 1000000)
while (num < 1)
{
int loop = 0;
sw.WriteLine("<test>");
while(loop <=10)
{
sw.WriteLine("<test1>99999</test1>");
sw.WriteLine("<test2>1900-01-01-01</test2>");
sw.WriteLine("<test3>99999</test3>");
sw.WriteLine("<test4>99999</test4>");
sw.WriteLine("<test5>99999</test5>");
sw.WriteLine("<test6>99999</test6>");
sw.WriteLine("<test7>99999</test7>");
sw.WriteLine("<test8>99999</test8>");
sw.WriteLine("<test9>99999</test9>");
sw.WriteLine("<test10>99999</test10>");
loop++;
}
sw.WriteLine("</test>");
num++;
}
sw.WriteLine("</root>");
sw.Close();
}
}



ファイル読み込み:

class Program
{
static void Main(string[] args)
{
string filename = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
string path = System.IO.Path.GetDirectoryName(filename);

XmlTextReader reader = new XmlTextReader(path + "\\test.xml");
reader.WhitespaceHandling = WhitespaceHandling.None;
reader.ReadStartElement();

XmlDocument doc = new XmlDocument();
XmlNode node;

while(reader.NodeType == XmlNodeType.Element)
{
try
{
node = doc.ReadNode(reader);
//Console.WriteLine(node.ToString());
}
catch(Exception e)
{
Console.WriteLine(e.Message.ToString());
}
}
}
}

補足日時:2007/07/12 19:50
    • good
    • 0
この回答へのお礼

himajin100000様

ご回答ありがとうございます。

的確な回答をいただき、感動いたしました。

ご回答を手掛かりに以下のことを試したところ、やはり.NET Framework 1.1
のXMLDocument.ReadNode()は2GBを超えるファイルを扱うことができなさそう
です。

VisualStudio 2003(.NET Framework 1.1)
・2GB未満のXMLファイルを生成し、ReadNode()で読み込む
 → エラーは発生しない。
・2GBより大きいXMLファイルを生成し、ReadNode()で読み込む
 → IndexOutOfRangeExceptionが発生した。

VisualStudio 2005.NET Framework 2.0)
・2GB未満のXMLファイルを生成し、ReadNode()で読み込む
 → エラーは発生しない。
・2GBより大きいXMLファイルを生成し、ReadNode()で読み込む
 → エラーは発生しない。

ありがとうございました。

お礼日時:2007/07/12 19:50

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!