问题:我有一个非常大的(300MB +)文本文件,它使用STX和ETX控制字符进行一些有趣的格式化。例如:
public System.Web.UI.Page requestVar;
有数百个(如果不是数千个)我称之为“块”的xml消息,每个消息都封装在STX和ETX控制字符之间。这些消息可以跨越多行,而不仅仅是一行。
在解析文件时,我需要能够找到每个xml块以进行单独解析。
我假设一个简单的缓冲流阅读器可以在这里工作,但我需要能够跟踪我正在阅读的位置,以便在控制字符之间拉出每个单独的xml块,直到我到达文件的末尾。
我想我可以用这个简单的方法读取文件:
public System.Web.UI.Page requestVar = new Page();
但是,在处理这些STX和ETX控制字符时,如何设置索引(开始/结束)?
答案 0 :(得分:0)
尝试以下代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string INPUT_FILENAME = @"c:\temp\test1.txt";
const string OUTPUT_FILENAME = @"c:\temp\test2.txt";
enum State
{
FIND_STX,
READ_DATA
}
static void Main(string[] args)
{
char STX = Encoding.UTF8.GetString(new byte[] { 0x02 }).First();
char ETX = Encoding.UTF8.GetString(new byte[] { 0x03 }).First();
string testMessage = string.Format("plain txt info{0}<xml ..xml message data.. /xml>{1}", STX, ETX);
StreamReader reader = null;
StreamWriter writer = null;
//write test output file
writer = new StreamWriter(INPUT_FILENAME, false, Encoding.UTF8);
for (int i = 0; i < 100; i++)
{
writer.WriteLine(testMessage);
}
writer.Flush();
writer.Close();
//now read test file
reader = new StreamReader(INPUT_FILENAME, Encoding.UTF8);
writer = new StreamWriter(OUTPUT_FILENAME, false, Encoding.UTF8);
char[] newChar = new char[1];
State state = State.FIND_STX;
while (!reader.EndOfStream)
{
reader.Read(newChar, 0, 1);
switch (state)
{
case State.FIND_STX :
if (newChar[0] == STX)
{
state = State.READ_DATA;
}
break;
case State.READ_DATA :
if (newChar[0] == ETX)
{
state = State.FIND_STX;
}
else
{
writer.Write(newChar[0]);
}
break;
}
}
writer.Flush();
writer.Close();
reader.Close();
}
}
}
答案 1 :(得分:0)
使用一些VB,这是我到目前为止所提出的,这是有效但似乎非常低效。
Dim sr As New StreamReader(dataFile)
Dim line As String = ""
Dim text As String = ""
While sr.Peek > -1
line = sr.ReadLine
Dim startPos = line.IndexOf(Chr(2)) + 1
Dim isTrue As Boolean = True
While isTrue
'if line contains ETX, get its position else just keep reading
Dim endPos = line.IndexOf(Chr(3))
If endPos = -1 Then
text += line.Substring(startPos)
line = sr.ReadLine
startPos = 0
Else
text += line.Substring(startPos, line.LastIndexOf(Chr(3)))
isTrue = False
End If
End While
'do something with the text here then reset text and keep going
text = ""
End While
这实际上设置了&#34; text&#34;是一个完整的xml消息,这是我正在寻找的,但我想知道这是否足够有效的非常大的文件。