我有一个奇怪的问题。所以我的代码如下:
exe从用户那里获取一些数据
调用Web服务在特定网络位置(例如\ some-server \ some-directory)写入文件(并为数据创建CSV)。 虽然此Web服务托管在同一位置 文件夹是(即我也可以将其更改为c:\ some-directory)。然后呢 写完文件后返回
exe检查文件是否存在,如果该文件存在则进一步处理其他错误。
我遇到的问题是在第3步。当我尝试在文件写入后立即读取文件时,我总是得到文件未找到异常(但文件存在)。我在调试时没有得到这个异常(因为那时我通过调试代码来延迟)或者在读取文件之前Thread.Sleep(3000)
。
这很奇怪,因为我在返回exe之前关闭了StreamWriter
。现在根据文档,close应强制刷新流。这也与文件的大小无关。此外,我没有进行异步线程调用来写入和读取文件。它们一个接一个地串行运行在同一个线程中(只有写入由Web服务完成,读取由exe完成。仍然是串行调用)
我不知道,但感觉文件实际写在磁盘上和执行Close()
时有一些时间差异。然而这令人困惑,因为这与尺寸无关。这适用于所有文件大小。我已尝试使用包含10,50,100,200行数据的文件。
我怀疑的另一件事是自从我将此文件写入网络位置以来,可能是Windows通过首先写入缓存然后写入网络位置来优化调用。所以我继续改变代码将其写在驱动器上(即使用c:\ some-directory),而不是网络位置。但它也导致同样的错误。
代码中没有错误(用于读写)。如前所述,通过延迟,它开始正常工作。其他一些有用的信息
修改1
File.AppendAllText()
不是正确的解决方案,因为它创建了一个新文件,如果它没有退出
编辑2 写作代码
using (FileStream fs = new FileStream(outFileName, FileMode.Create))
{
using (StreamWriter writer = new StreamWriter(fs, Encoding.Unicode))
{
writer.WriteLine(someString)
}
}
阅读代码
StreamReader rdr = new StreamReader(File.OpenRead(CsvFilePath));
string header = rdr.ReadLine();
rdr.Close();
编辑3 使用textwriter,同样的错误
using (TextWriter writer = File.CreateText(outFileName))
{
}
编辑3 最后,正如一些用户所建议的那样,在抛出未找到文件的异常之前,我正在检查while循环中的文件一定次数。
int i = 1;
while (i++ < 10)
{
bool fileExists = File.Exists(CsvFilePath);
if (!fileExists)
System.Threading.Thread.Sleep(500);
else
break;
}
答案 0 :(得分:1)
所以你正在写一个文件流,然后将文件读回一个流?您是否需要编写文件然后对其进行处理,或者您是否可以直接使用源流?
如果你需要这个文件,我会使用一个循环来持续检查文件是否每秒都存在直到它出现(或者经过了一段时间) - 如果你不能写的话,作者会给你一个错误该文件,所以你知道它最终会出现。
答案 1 :(得分:0)
由于您是通过网络编写的,因此最佳解决方案是首先将文件保存在本地系统中,然后将其复制到网络位置。这样可以避免网络连接问题。并且在网络出现故障的情况下也有备份。
根据您的更新,请改为尝试:
File.WriteAllText(outFileName, someString);
header = null;
using(StreamReader reader = new StreamReader(CsvFilePath)) {
header = reader.ReadLine();
}
答案 2 :(得分:0)
在处理编写器FileStream后,您是否尝试阅读?
像这样:
using (FileStream fs = new FileStream(outFileName, FileMode.Create))
{
using (StreamWriter writer = new StreamWriter(fs, Encoding.Unicode))
{
writer.WriteLine(someString)
}
}
using (StreamReader rdr = new StreamReader(File.OpenRead(CsvFilePath)))
{
string header = rdr.ReadLine();
}