我试图用两种不同的方法读取.json文件,如下所示:
void mainMethod()
{
Stream theFile = Assembly.GetExecutingAssembly().GetManifestResourcesStream("pathToFile");
Method1(theFile);
Method2(theFile);
}
void Method1(Stream file)
{
using (StreamReader fileUsage_1 = new StreamReader(file))
{
//do stuff with file
}
}
void Method2(Stream file)
{
using (StreamReader fileUsage_2 = new StreamReader(file))
{
//do stuff with file
}
}
运行mainMethod()
会在Stream was not readable.
中出现例外:Method2()
我认为问题是Method2()
正在尝试阅读theFile
在Method1()
中使用。我以为using
块会自动关闭文件?如何在theFile
和Method1()
中自定义我正在阅读Method2()
的方式,以便它们不会“重叠”?
答案 0 :(得分:2)
打开StreamReader一次,并在每个方法中设置位置。这样,调用方法的顺序不固定。当您第一次打开StreamReader时,默认情况下将位置设置为开头,因此第一次调用Seek(0,SeekOrigin.Begin)是多余的,但允许将来调用的顺序可以互换。
void mainMethod()
{
Stream theFile = Assembly.GetExecutingAssembly().GetManifestResourcesStream("pathToFile");
using (StreamReader fileUsage = new StreamReader(theFile))
{
Method1(fileUsage);
Method2(fileUsage);
}
}
private static void Method1(StreamReader fileUsage)
{
if (fileUsage != null && fileUsage.BaseStream.CanSeek && fileUsage.BaseStream.CanRead)
{
fileUsage.BaseStream.Seek(0, SeekOrigin.Begin);
fileUsage.DiscardBufferedData();
Console.WriteLine(fileUsage.ReadLine());
}
}
答案 1 :(得分:1)
叫我疯了......但你不能简单地从方法中抽象出使用声明并进入主程序吗?像这样。编辑包括重置位置,如果您选择这样做。 (可以转到Here以获取有关丢弃缓冲区数据的更多信息)
namespace ConsoleApplication12
{
class Program
{
static void Main(string[] args)
{
Stream theFile = Assembly.GetExecutingAssembly().GetManifestResourceStream("ConsoleApplication12.test.txt");
using (StreamReader fileUsage_1 = new StreamReader(theFile))
{
Method1(fileUsage_1);
ResetPosition(theFile, fileUsage_1); // If needed
Method2(fileUsage_1);
}
Console.ReadLine();
}
private static void Method2(StreamReader fileUsage)
{
var test = fileUsage.ReadLine();
}
private static void Method1(StreamReader fileUsage)
{
var test = fileUsage.ReadLine();
}
private static void ResetPosition(Stream s, StreamReader sr)
{
s.Position = 0;
sr.DiscardBufferedData();
}
}
}
答案 2 :(得分:0)
如果符合以下条件,则可以重新读取整个流:
stream.CanSeek == true
)您通常无法控制1,但如果需要,您可以将整个srteam复制到可搜索的位置(即使用Stream.Copy
到MemoryStream
)。
要阻止读者关闭流 - 请使用不取得流所有权的构造函数,因为reslut在使用后不会关闭流。即StreamReader(...,bool leaveOpen)
最后,你需要寻找一个流来定位其他读者需要开始(通常是开始)的地方,例如Stream.Position = 0;
注释
Method2
从您不需要Method1
离开的地方阅读流,请确保读者不要关闭。using
/ .Close
来电),但这样的代码看起来不对,当一个人通过添加using
“修复”它时,它将不再工作正常。答案 3 :(得分:0)
如前所述设置Stream.Position。 这样设置:
file.Seek(System.IO.SeekOrigin.Begin);
StreamReader上的Using块在退出时关闭底层流。您可以使用File.ReadAllText方法通过该单个调用打开,读取和关闭(处置)文件:
string jsonString = File.ReadAllText(filePath);