繁体   English   中英

System.IO.IOException: '进程无法访问文件 '@.txt',因为它正被另一个进程使用。

[英]System.IO.IOException: 'The process cannot access the file '@.txt' because it is being used by another process.'

我是编程新手,我有一个问题。 如果我有两个函数,一个创建一个文本文件并写入其中,另一个打开同一个文本文件并从中读取。

我得到的错误是:

System.IO.IOException: '进程无法访问文件 '@.txt',因为它正被另一个进程使用。

我尝试为每个功能设置单独的计时器,但它仍然不起作用。 我认为最好的方法是功能二直到功能一结束才开始。

你能帮我实现这个目标吗? 非常感谢! 迈克

源代码:

public Form1() {
    InitializeComponent();
    System.Timers.Timer timerButtona1 = new System.Timers.Timer();
    timerButtona1.Elapsed += new ElapsedEventHandler(tickTimera1);
    timerButtona1.Interval = 3003;
    timerButtona1.Enabled = true;
}

private async void tickTimera1(object source, ElapsedEventArgs e) {
    function1();
    function2();
}

void function1() {
    List<string> linki = new List<string>();

    linki.Add("https://link1.net/");
    linki.Add("https://link2.net/");
    linki.Add("https://link3.net/");

    List<string> fileNames = new List<string>();

    fileNames.Add("name1");
    fileNames.Add("name2");
    fileNames.Add("name3");

    for (int x = 0; x < fileNames.Count; x++) {
        GET(linki[x], fileNames[x]);
        //System.Threading.Thread.Sleep(6000);
    }
}

async void GET(string link, string fileName) {
    var ODGOVOR = await PRENOS_PODATKOV.GetStringAsync(link);
    File.WriteAllText(@"C:\Users\...\" + fileName + ".txt", ODGOVOR);
}

void function2() {
    string originalText = File.ReadAllText(@"C:\Users\...\fileName.txt", Encoding.Default);
    dynamic modifiedText = JsonConvert.DeserializeObject(originalText);
    //then i then i read from the same text files and use some data from it..
}

您必须在编辑后关闭该文件。

var myFile = File.Create(myPath);
//myPath = "C:\file.txt"
myFile.Close();
//closes the text file for eg. file.txt
//You can write your reading functions now..

关闭后,您可以再次使用它(供阅读)

问题是有时文件锁在关闭后不会立即释放。

您可以尝试运行循环来读取文件。 在循环内放置一个 try catch 语句,如果文件读取成功,则中断循环。 否则,等待几毫秒并再次尝试读取文件:

string originalText = null;
while (true)
{
    try
    {
        originalText = File.ReadAllText(@"C:\Users\...\fileName.txt", Encoding.Default);
        break;
    }
    catch 
    { 
        System.Threading.Thread.Sleep(100);
    }
}

编写文本文件后,您应该先关闭它,然后再继续执行第二个功能:

var myFile = File.Create(myPath);
//some other operations here like writing into the text file
myFile.Close(); //close text file
//call your 2nd function here

简单说一下:

public void Start() {
    string filename = "myFile.txt";
    CreateFile(filename); //call your create textfile method
    ReadFile(filename); //call read file method
}

public void CreateFile(string filename) {
    var myFile = File.Create(myPath); //create file
    //some other operations here like writing into the text file
    myFile.Close(); //close text file
}

public void ReadFile(string filename) {
    string text;
    var fileStream = new FileStream(filename, FileMode.Open, 
    FileAccess.Read); //open text file
    //vvv read text file (or however you implement it like here vvv
    using (var streamReader = new StreamReader(fileStream, Encoding.UTF8))
    {
        text = streamReader.ReadToEnd();
    }
    //finally, close text file
    fileStream.Close();
}

关键是,在完成对文件的任何操作后,您必须关闭 FileStream。 您可以通过myFileStream.Close()执行此myFileStream.Close()

此外, File.Create(filename)返回一个FileStream对象,然后您可以Close()

实际上这不是关闭/处理流的问题, File.WriteAllTextFile.ReadAllText在内部完成。

问题是因为错误使用了async/await模式。 GET是异步,但从来没有期待,从而导致function1上完成,并移动到function2之前的所有内容实际写入到文件中。

它的编写方式GET是不可等待的,因为它是async void ,除非您正在处理事件或真正知道您在做什么,否则永远不应使用它。

因此,要么完全删除async/await的使用,要么一直保持async

  1. GET更改为可等待:

     async Task GET(string link, string fileName)
  2. 在 now async function1等待它:

     async Task function1() { ... for (int x = 0; x < fileNames.Count; x++) { await GET(linki[x], fileNames[x]); //System.Threading.Thread.Sleep(6000); } ...
  3. Elapsed事件中等待function1

     private async void tickTimera1(object source, ElapsedEventArgs e) { await function1(); function2(); }

创建一个文件,然后关闭它。 之后可以将数据保存到该文件中。 我做了如下。

if (!File.Exists(filePath))
{
    File.Create(filePath).Close();
}
File.WriteAllText(filePath, saveDataString)

在其中一个单元测试中,我必须创建一个临时文件,然后将其删除,然后出现上述错误。

没有一个答案奏效。 有效的解决方案是:

var path = $"temp.{extension}";
        using (File.Create(path))
        {
        }


        File.Delete(path);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM