C# 如何在C中的循环或递归函数中多次访问文件#
我使用以下方法打印树中的节点。此方法存在于一个应用程序类中C# 如何在C中的循环或递归函数中多次访问文件#,c#,recursion,file-io,C#,Recursion,File Io,我使用以下方法打印树中的节点。此方法存在于一个应用程序类中 using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace AUV_Topology { class SpanningTree { public static Graph graph =
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace AUV_Topology
{
class SpanningTree
{
public static Graph graph = null;
public static SpanningTree root = new SpanningTree();
public static FileStream fs = new FileStream ("C:/Users/Welcome/Desktop/SpanningTree.txt", FileMode.Append, FileAccess.Write);
public static void Print(SpanningTree parent, int level)
{
using (StreamWriter sw = new StreamWriter(fs))
{
sw.WriteLine("----------------------------------------------------------------------------------------");
sw.WriteLine("{0} Level : '{1}' ", new string(' ', 4 * level),level);
sw.WriteLine(" , Row : '{0}', Col : '{1}'",parent.row, parent.col);
sw.WriteLine("Length : '{0}'", parent.length);
sw.WriteLine("----------------------------------------------------------------------------------------");
if (parent.children != null)
{
foreach (SpanningTree child in parent.children)
{
Print(child, level + 1);
}
}
}
}
}
}
我运行代码时出错,如下所示(
在“foreach”声明中:
无法访问已关闭的文件
作为其
Dispose
逻辑的一部分,StreamWriter
实例将关闭底层流。因此,一种解决方案是将FileStream
实例的创建移到Print
方法中
在这种情况下,为了正确处置资源,可以执行以下操作:
public static void Print(SpanningTree parent, int level)
{
FileStream fs = new FileStream("C:/Users/Welcome/Desktop/SpanningTree.txt", FileMode.Append, FileAccess.Write);
using (StreamWriter sw = new StreamWriter(fs))
{
Print(parent, level, sw);
}
}
private static void Print(SpanningTree parent, int level, StreamWriter sw)
{
sw.WriteLine("----------------------------------------------------------------------------------------");
sw.WriteLine("{0} Level : '{1}' ", new string(' ', 4 * level), level);
sw.WriteLine(" , Row : '{0}', Col : '{1}'", parent.row, parent.col);
sw.WriteLine("Length : '{0}'", parent.length);
sw.WriteLine("----------------------------------------------------------------------------------------");
if (parent.children != null)
{
foreach (SpanningTree child in parent.children)
{
Print(child, level + 1, sw);
}
}
}
private static IEnumerable<String> Data(SpanningTree tree, int level) {
yield return $"-----------------------------------------------------------------";
yield return $"{new string(' ', 4 * level)} Level : '{level}' ";
yield return $" , Row : '{parent.row}', Col : '{parent.col}'";
yield return $"Length : '{parent.length}'";
yield return $"-----------------------------------------------------------------";
if (parent.children != null)
foreach (SpanningTree child in parent.children)
foreach (string line in Data(child, level + 1))
yield return line;
}
另一种解决方案是使用StreamWriter
类型的替代构造函数
public StreamWriter(Stream stream, Encoding encoding, int bufferSize, bool leaveOpen)
并将true
传递给最后一个参数leaveOpen
。在这种情况下,您需要确保在方法之外的某个地方处置资源
我个人建议您使用第一种方法—它稍微简单一点,而且看起来不像是性能关键型代码…作为其
Dispose
逻辑的一部分,StreamWriter
实例将关闭底层流。因此,一种解决方案是将FileStream
实例的创建移到Print
方法中
在这种情况下,为了正确处置资源,可以执行以下操作:
public static void Print(SpanningTree parent, int level)
{
FileStream fs = new FileStream("C:/Users/Welcome/Desktop/SpanningTree.txt", FileMode.Append, FileAccess.Write);
using (StreamWriter sw = new StreamWriter(fs))
{
Print(parent, level, sw);
}
}
private static void Print(SpanningTree parent, int level, StreamWriter sw)
{
sw.WriteLine("----------------------------------------------------------------------------------------");
sw.WriteLine("{0} Level : '{1}' ", new string(' ', 4 * level), level);
sw.WriteLine(" , Row : '{0}', Col : '{1}'", parent.row, parent.col);
sw.WriteLine("Length : '{0}'", parent.length);
sw.WriteLine("----------------------------------------------------------------------------------------");
if (parent.children != null)
{
foreach (SpanningTree child in parent.children)
{
Print(child, level + 1, sw);
}
}
}
private static IEnumerable<String> Data(SpanningTree tree, int level) {
yield return $"-----------------------------------------------------------------";
yield return $"{new string(' ', 4 * level)} Level : '{level}' ";
yield return $" , Row : '{parent.row}', Col : '{parent.col}'";
yield return $"Length : '{parent.length}'";
yield return $"-----------------------------------------------------------------";
if (parent.children != null)
foreach (SpanningTree child in parent.children)
foreach (string line in Data(child, level + 1))
yield return line;
}
另一种解决方案是使用StreamWriter
类型的替代构造函数
public StreamWriter(Stream stream, Encoding encoding, int bufferSize, bool leaveOpen)
并将true
传递给最后一个参数leaveOpen
。在这种情况下,您需要确保在方法之外的某个地方处置资源
我个人建议您使用第一种方法-它稍微简单一点,而且看起来不像性能关键的代码…默认情况下,
StreamWriter
将关闭/处理底层的流
有一个重载构造函数,您可以在其中传递使流保持打开状态的选项
但我会选择不同的逻辑
public static void Print(
SpanningTree root,
string filename )
{
FileStream fs = new FileStream( filename, FileMode.Append, FileAccess.Write );
using ( StreamWriter sw = new StreamWriter( fs ) )
{
PrivatePrint( root, 0, sw );
}
}
private static void PrivatePrint(
SpanningTree parent,
int level,
StreamWriter sw )
{
sw.WriteLine( "----------------------------------------------------------------------------------------" );
sw.WriteLine( "{0} Level : '{1}' ", new string(' ', 4 * level), level );
sw.WriteLine( " , Row : '{0}', Col : '{1}'", parent.row, parent.col );
sw.WriteLine( "Length : '{0}'", parent.length );
sw.WriteLine( "----------------------------------------------------------------------------------------" );
if ( parent.children != null )
{
foreach ( SpanningTree child in parent.children )
{
PrivatePrint( child, level + 1, sw );
}
}
}
默认情况下,StreamWriter
将关闭/处理底层流
有一个重载构造函数,您可以在其中传递使流保持打开状态的选项
但我会选择不同的逻辑
public static void Print(
SpanningTree root,
string filename )
{
FileStream fs = new FileStream( filename, FileMode.Append, FileAccess.Write );
using ( StreamWriter sw = new StreamWriter( fs ) )
{
PrivatePrint( root, 0, sw );
}
}
private static void PrivatePrint(
SpanningTree parent,
int level,
StreamWriter sw )
{
sw.WriteLine( "----------------------------------------------------------------------------------------" );
sw.WriteLine( "{0} Level : '{1}' ", new string(' ', 4 * level), level );
sw.WriteLine( " , Row : '{0}', Col : '{1}'", parent.row, parent.col );
sw.WriteLine( "Length : '{0}'", parent.length );
sw.WriteLine( "----------------------------------------------------------------------------------------" );
if ( parent.children != null )
{
foreach ( SpanningTree child in parent.children )
{
PrivatePrint( child, level + 1, sw );
}
}
}
不能以递归方式使用using语句。原因如下:
在最后一个递归调用完成后,它将处理资源(using语句超出范围)。当倒数第二个递归调用尝试处置资源时(其using语句超出范围),它会抛出异常,因为资源已被处置
考虑以下显示相同行为的控制台应用程序代码:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
internal class Program
{
public static FileStream fs = new FileStream("C:/Test/SpanningTree.txt", FileMode.Append,
FileAccess.Write);
public static void Print(int level)
{
using (StreamWriter sw = new StreamWriter(fs))
{
sw.WriteLine("----------------------------------------------------------------------------------------");
sw.WriteLine("{0} Level : '{1}' ", new string(' ', 4*level), level);
sw.WriteLine("----------------------------------------------------------------------------------------");
if (level < 10)
{
Print(level + 1);
}
}
}
private static void Main(string[] args)
{
Print(1);
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.IO;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
命名空间控制台应用程序1
{
内部课程计划
{
publicstaticfilestreamfs=newfilestream(“C:/Test/SpanningTree.txt”,FileMode.Append,
FileAccess.Write);
公共静态无效打印(整数级)
{
使用(StreamWriter sw=新StreamWriter(fs))
{
sw.WriteLine(“----------------------------------------------------------------------------------------------------”);
sw.WriteLine(“{0}级:{1}”,新字符串(“”,4*Level),Level);
sw.WriteLine(“----------------------------------------------------------------------------------------------------”);
如果(级别<10)
{
打印(级别+1);
}
}
}
私有静态void Main(字符串[]args)
{
印刷品(1);
}
}
}
有许多方法可以解决此问题,我将在下面演示其中一种:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
internal class Program
{
public static FileStream fs = new FileStream("C:/Test/SpanningTree.txt", FileMode.Append,
FileAccess.Write);
public static void Print(StreamWriter sw, int level)
{
sw.WriteLine("----------------------------------------------------------------------------------------");
sw.WriteLine("{0} Level : '{1}' ", new string(' ', 4 * level), level);
sw.WriteLine("----------------------------------------------------------------------------------------");
if (level < 10)
{
Print(level + 1);
}
}
private static void Main(string[] args)
{
using (StreamWriter sw = new StreamWriter(fs))
{
Print(1);
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.IO;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
命名空间控制台应用程序1
{
内部课程计划
{
publicstaticfilestreamfs=newfilestream(“C:/Test/SpanningTree.txt”,FileMode.Append,
FileAccess.Write);
公共静态无效打印(StreamWriter sw,整数级)
{
sw.WriteLine(“----------------------------------------------------------------------------------------------------”);
sw.WriteLine(“{0}级:{1}”,新字符串(“”,4*Level),Level);
sw.WriteLine(“----------------------------------------------------------------------------------------------------”);
如果(级别<10)
{
打印(级别+1);
}
}
私有静态void Main(字符串[]args)
{
使用(StreamWriter sw=新StreamWriter(fs))
{
印刷品(1);
}
}
}
}
不能以递归方式使用using语句。原因如下:
在最后一个递归调用完成后,它将处理资源(using语句超出范围)。当倒数第二个递归调用尝试处置资源时(其using语句超出范围),它会抛出异常,因为资源已被处置
考虑以下显示相同行为的控制台应用程序代码:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
internal class Program
{
public static FileStream fs = new FileStream("C:/Test/SpanningTree.txt", FileMode.Append,
FileAccess.Write);
public static void Print(int level)
{
using (StreamWriter sw = new StreamWriter(fs))
{
sw.WriteLine("----------------------------------------------------------------------------------------");
sw.WriteLine("{0} Level : '{1}' ", new string(' ', 4*level), level);
sw.WriteLine("----------------------------------------------------------------------------------------");
if (level < 10)
{
Print(level + 1);
}
}
}
private static void Main(string[] args)
{
Print(1);
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.IO;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
命名空间控制台应用程序1
{
内部课程计划
{
publicstaticfilestreamfs=newfilestream(“C:/Test/SpanningTree.txt”,FileMode.Append,
FileAccess.Write);
公共静态无效打印(整数级)
{
使用(StreamWriter sw=新StreamWriter(fs))
{
西南书写线(“------------------------------------------------