C# 不会无缘无故地中断循环
我正在编写一些解析 Apache 配置文件的代码。
文件im解析:
NameVirtualHost *:80
#
# VirtualHost example:
# Almost any Apache directive may go into a VirtualHost container.
# The first VirtualHost section is used for all requests that do not
# match a ServerName or ServerAlias in any <VirtualHost> block.
#
<VirtualHost *:80>
ServerAdmin [email protected]
DocumentRoot "c:/Apache2/docs/dummy-host.example.com"
ServerName dummy-host.example.com
ServerAlias www.dummy-host.example.com
ErrorLog "logs/dummy-host.example.com-error.log"
CustomLog "logs/dummy-host.example.com-access.log" common
</VirtualHost>
<VirtualHost *:80>
ServerAdmin [email protected]
DocumentRoot "c:/Apache2/docs/dummy-host2.example.com"
ServerName dummy-host2.example.com
ErrorLog "logs/dummy-host2.example.com-error.log"
CustomLog "logs/dummy-host2.example.com-access.log" common
</VirtualHost>
这是解析器方法filePath是上面文件的路径。
public void readFile(string filePath)
{
/* read the file path provided */
StreamReader reader = new StreamReader(filePath);
string content = reader.ReadToEnd();
/* remove the comments from the file */
string[] lines = content.Split('\n');
string newContent = "";
foreach(string line in lines){
char[] chars = line.ToCharArray();
if(chars[0] != '#'){
newContent += line+"\n";
}
}
/* search for Virtual hosts and save them */
string regEx = "<VirtualHost [^>]*>[^<]*</VirtualHost>";
MatchCollection coll = Regex.Matches(newContent, regEx, RegexOptions.IgnoreCase);
string[] vhosts = new string[coll.Count];
int counter = 0;
/* go though them and save them into a string array */
foreach (Match match in coll)
{
vhosts[counter] = (match.Value);
counter++;
}
/* set the number of vhosts */
hosts = new vhost[vhosts.Count()];
/* go though the string array */
for (int c = 0; c < vhosts.Count(); c++ )
{
MessageBox.Show("hi");
/* set the host string to current vhost string */
string host = vhosts[c];
/* get the lines from the vhost */
string[] lines2 = host.Split('\n');
/* create the new save object in the array of vhosts */
hosts[c] = new vhost();
/* tell the console what were proccessing */
Console.WriteLine((c+1).ToString() + " of " + vhosts.Count().ToString());
/* for each line add the rule to the correct vHost via the counter for looping though the vhosts */
for (int i = 0; i < lines2.Count(); i++)
{
/* set the string line to the line were currently on */
string line = lines2[i];
/* get rid of whitespace and split on the space (' ')*/
string[] param = line.Trim().Split(' ');
/* provde the current vHost number and the key and value in the config file */
hosts[c].addRule(param[0], param[1]);
}
}
}
hosts
是一个 vHost[]
vHost 如下
class vhost
{
public vhostRules[] rules = new vhostRules[1];
public string getRuleValue(string key)
{
vhostRules[] currentRules = rules;
rules = new vhostRules[currentRules.Count()];
for (int i = 0; i < currentRules.Count(); i++)
{
vhostRules Rule = currentRules[i];
if (key == Rule.key)
return Rule.value;
}
return "";
}
public vhostRules getRule(string key)
{
vhostRules[] currentRules = rules;
rules = new vhostRules[currentRules.Count()];
for (int i = 0; i < currentRules.Count(); i++)
{
vhostRules Rule = currentRules[i];
if (key == Rule.key)
return Rule;
}
return new vhostRules();
}
public vhostRules[] getRules()
{
return rules;
}
public void addRule(string key, string rule)
{
vhostRules[] currentRules = rules;
rules = new vhostRules[currentRules.Count()];
int counter = 0;
for (int i = 0; i < currentRules.Count(); i++)
{
vhostRules Rule = currentRules[i];
rules[i] = Rule;
counter++;
}
rules[counter] = new vhostRules();
rules[counter].key = key;
rules[counter].value = rule;
}
public void removeRule(string key)
{
vhostRules[] currentRules = rules;
rules = new vhostRules[currentRules.Count()];
for (int i = 0; i < currentRules.Count(); i++)
{
vhostRules Rule = currentRules[i];
if (key != Rule.key)
rules[i] = Rule;
}
}
public void changeRule(string key, string value)
{
vhostRules[] currentRules = rules;
rules = new vhostRules[currentRules.Count()];
for (int i = 0; i < currentRules.Count(); i++)
{
vhostRules Rule = currentRules[i];
if (key != Rule.key)
{
rules[i] = Rule;
rules[i].value = value;
}
}
}
}
vhostRules 对象
class vhostRules { public string key;公共字符串值; }
和 vhostRules
基本上是一个保存键和值的类
现在的问题是 hosts[c].addRule(param[0], param[1]); ,您可以看到它在类
vhost
中再次调用 addRule
,即使我清空 addRule 所以里面没有代码,这仍然不会工作。
这是我可以显示问题的唯一方法,没有更小的方法可以复制,因为错误似乎与编译的最终结果有关
我找到的唯一方法是注释或删除 hosts[c].addRule( param[0], param[1]);
从我的代码中,它可以工作,但如上所述,当我清空它时,它不起作用,这在理论上是不正确的,
尽管代码确实如此,但不会发生错误,并且它仅运行循环一次,
不会发生任何错误,这包括无静默死亡、无异常、无冻结/崩溃
更新 更新的阅读器
try
{
hosts[c].addRule(param[0], param[1]);
}catch (Exception e) { Console.WriteLine(e.Message); }
提供输出
1 of 2
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
2 of 2
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
断点信息
param = {string[2]}
[0] = "ServerAdmin"
[1] = "webmaste
I'm writing some code that parses an Apache config file.
The File im parsing:
NameVirtualHost *:80
#
# VirtualHost example:
# Almost any Apache directive may go into a VirtualHost container.
# The first VirtualHost section is used for all requests that do not
# match a ServerName or ServerAlias in any <VirtualHost> block.
#
<VirtualHost *:80>
ServerAdmin [email protected]
DocumentRoot "c:/Apache2/docs/dummy-host.example.com"
ServerName dummy-host.example.com
ServerAlias www.dummy-host.example.com
ErrorLog "logs/dummy-host.example.com-error.log"
CustomLog "logs/dummy-host.example.com-access.log" common
</VirtualHost>
<VirtualHost *:80>
ServerAdmin [email protected]
DocumentRoot "c:/Apache2/docs/dummy-host2.example.com"
ServerName dummy-host2.example.com
ErrorLog "logs/dummy-host2.example.com-error.log"
CustomLog "logs/dummy-host2.example.com-access.log" common
</VirtualHost>
This is the parser method filePath is the path to the above file.
public void readFile(string filePath)
{
/* read the file path provided */
StreamReader reader = new StreamReader(filePath);
string content = reader.ReadToEnd();
/* remove the comments from the file */
string[] lines = content.Split('\n');
string newContent = "";
foreach(string line in lines){
char[] chars = line.ToCharArray();
if(chars[0] != '#'){
newContent += line+"\n";
}
}
/* search for Virtual hosts and save them */
string regEx = "<VirtualHost [^>]*>[^<]*</VirtualHost>";
MatchCollection coll = Regex.Matches(newContent, regEx, RegexOptions.IgnoreCase);
string[] vhosts = new string[coll.Count];
int counter = 0;
/* go though them and save them into a string array */
foreach (Match match in coll)
{
vhosts[counter] = (match.Value);
counter++;
}
/* set the number of vhosts */
hosts = new vhost[vhosts.Count()];
/* go though the string array */
for (int c = 0; c < vhosts.Count(); c++ )
{
MessageBox.Show("hi");
/* set the host string to current vhost string */
string host = vhosts[c];
/* get the lines from the vhost */
string[] lines2 = host.Split('\n');
/* create the new save object in the array of vhosts */
hosts[c] = new vhost();
/* tell the console what were proccessing */
Console.WriteLine((c+1).ToString() + " of " + vhosts.Count().ToString());
/* for each line add the rule to the correct vHost via the counter for looping though the vhosts */
for (int i = 0; i < lines2.Count(); i++)
{
/* set the string line to the line were currently on */
string line = lines2[i];
/* get rid of whitespace and split on the space (' ')*/
string[] param = line.Trim().Split(' ');
/* provde the current vHost number and the key and value in the config file */
hosts[c].addRule(param[0], param[1]);
}
}
}
hosts
is a vHost[]
vHost is as below
class vhost
{
public vhostRules[] rules = new vhostRules[1];
public string getRuleValue(string key)
{
vhostRules[] currentRules = rules;
rules = new vhostRules[currentRules.Count()];
for (int i = 0; i < currentRules.Count(); i++)
{
vhostRules Rule = currentRules[i];
if (key == Rule.key)
return Rule.value;
}
return "";
}
public vhostRules getRule(string key)
{
vhostRules[] currentRules = rules;
rules = new vhostRules[currentRules.Count()];
for (int i = 0; i < currentRules.Count(); i++)
{
vhostRules Rule = currentRules[i];
if (key == Rule.key)
return Rule;
}
return new vhostRules();
}
public vhostRules[] getRules()
{
return rules;
}
public void addRule(string key, string rule)
{
vhostRules[] currentRules = rules;
rules = new vhostRules[currentRules.Count()];
int counter = 0;
for (int i = 0; i < currentRules.Count(); i++)
{
vhostRules Rule = currentRules[i];
rules[i] = Rule;
counter++;
}
rules[counter] = new vhostRules();
rules[counter].key = key;
rules[counter].value = rule;
}
public void removeRule(string key)
{
vhostRules[] currentRules = rules;
rules = new vhostRules[currentRules.Count()];
for (int i = 0; i < currentRules.Count(); i++)
{
vhostRules Rule = currentRules[i];
if (key != Rule.key)
rules[i] = Rule;
}
}
public void changeRule(string key, string value)
{
vhostRules[] currentRules = rules;
rules = new vhostRules[currentRules.Count()];
for (int i = 0; i < currentRules.Count(); i++)
{
vhostRules Rule = currentRules[i];
if (key != Rule.key)
{
rules[i] = Rule;
rules[i].value = value;
}
}
}
}
The vhostRules Object
class vhostRules { public string key; public string value; }
and vhostRules
is basicly a class to save key and value
Now the problem is hosts[c].addRule(param[0], param[1]);
of the read file above as you can see its is calling addRule
as above again inside class vhost
even if i empty addRule so there is no code inside this still does not work.
This is the only way i can show the problem there is no smaller way to replicate as the error appears to be with the compiled end result
The only way i have found is the comment or remove the hosts[c].addRule(param[0], param[1]);
from my code then it works but as above when i empty it, it does not work that is theoretically incorrect
Stepping though the code does as its does no error occurs and it only runs the loop once,
NO ERRORS OCCUR THIS INCLUDES NO SILENT DEATH NO EXCEPTIONS AND NO FREEZING/CRASHING
update
Updated reader
try
{
hosts[c].addRule(param[0], param[1]);
}catch (Exception e) { Console.WriteLine(e.Message); }
Provides output
1 of 2
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
2 of 2
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
The Break point info
param = {string[2]}
[0] = "ServerAdmin"
[1] = "webmaste
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
只是为了提供一个实际的答案:
我最初的猜测 - 这只是一个猜测,因为我们没有我们需要的所有信息 - 是循环中的某个地方抛出了异常。
我能看到的最有可能的异常候选是这一行:
vhost
类中的 addRule 方法做了一些非常时髦的事情,但同样,我们没有所有信息,所以我可以'不敢肯定地说。我们需要什么
我们至少需要知道正在发生什么。是否抛出异常?它达到什么线?难道就这样悄无声息地死去吗?您单步执行过代码吗?
请帮助我们帮助您...
更新
因此,问题出在以下位置:
OR:
OR:
在
vhostRules
的构造函数内,如行所示:现在,您在
rules 内用于键值对的键是什么[]?
你可以尝试
将行:更改
为:
这将允许您在某些行的末尾保留
common
...这可能不会导致您的主要问题,但它可能是一个至少有一个问题。更新2
在上面的行 (
string[] param = line.Trim().Split(new char[] {' '}, 2);
之后设置一个断点,并查看 param 实际设置为什么。添加一个手表,确切看看 param[0] 和 param[1] 是什么,我感觉它们没问题,而且它实际上在 addRule 方法中的某个地方。正在抛出异常...因此,再次在 addRule 方法中的代码周围添加错误处理,并查看输出内容查看堆栈跟踪,检查行号,并向我们准确显示其中发生的情况。 。
Just to provide an actual answer on this:
My initial guess - and it is only a guess, as we don't have all the information we need - is that there is an exception being thrown somewhere within the loop.
The most likely candidate I can see for the exception is the line:
The addRule method within the
vhost
class does some pretty funky stuff, but again, we don't have all the info, so I can't say for sure.What we need
We will at least need to know what is happening. Is an exception being thrown? What line does it get up to? Does it silently die? Have you stepped through the code?
Please, help us to help you...
Update
So, the issue is somewhere in:
OR:
OR:
Within the constructor of
vhostRules
, as shown by the line:Now, what is the key you are using for the key value pair within
rules[]
?You could try
Changing the line:
to:
This will allow you to keep the
common
at the end of some of your lines... This is probably not causing your main issue, but it's likely to be an issue at least.Update 2
Set a breakpoint after the line above (
string[] param = line.Trim().Split(new char[] {' '}, 2);
, and see what param is actually set to. Add a watch, see exactly what param[0] and param[1] are. I have a feeling they're OK, and it's actually somewhere within the addRule method that the exception is being thrown...So again, add error handling around the code within the addRule method, and see what is being output. Look at the stack trace, check the line numbers, and show us exactly what is going on in there.
不是解决您的问题,但至少进行一些清理:更改此行:
然后
您不需要每次需要添加项目时重新复制该数组,只需
.Add()
它。然后你可能会
变成
Not a solution to your problem, but at least some cleanup: change this line:
into
then you don't need to recopy that array every time you need to add an item, just
.Add()
it.You might then change
into
我想我找到了。您对每个虚拟主机定义中的每一行执行此代码:
这假定每行至少包含 2 个空格分隔的值。对于所有这些都是如此除了最后一个:
。
我希望您得到一个 ArrayIndexOutOfBoundsException(或 .NET 中调用的任何内容),但似乎有什么东西吞掉了它。
I think I found it. You execute this code for each line in each virtual host definition:
This assumes that every line contains at least 2 space-separated values. That's true for all of them except for the last one:
</VirtualHost>
.I'd expect you to get an
ArrayIndexOutOfBoundsException
(or whatever that is called in .NET), but something seems to swallow that.