无法通过C#控制台应用程序中的System.IO.File删除某些文件 [英] Unable to delete some files via System.IO.File in C# console app

查看:138
本文介绍了无法通过C#控制台应用程序中的System.IO.File删除某些文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在加密一些文本文件.加密文件后工作正常,但是有时我在尝试删除原始未加密文件时收到此错误:

I am encrypting some text files. It works fine the file is encypted, however on occasion I get this error when attempting to delete the original unencrypted file:

System.IO.IOException: 该进程无法访问文件'MyFile.TXT',因为它正在被另一个进程使用.,位于System.IO .__ Error.WinIOError(Int32 errorCode,位于System.IO.File.Delete(String)上的String mayFullPath) 路径)在FileEncryption.Program.DeleteFile(String sInputFilename)中 FileEncryption \ Program.cs:第159行

System.IO.IOException: The process cannot access the file 'MyFile.TXT' because it is being used by another process. at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) at System.IO.File.Delete(String path) at FileEncryption.Program.DeleteFile(String sInputFilename) in FileEncryption\Program.cs:line 159

这似乎在大型文本文件上发生. (50MB +),但并非总是如此.

This seems to happen on large text files. (50MB+) but not always.

知道我可能做错了什么吗?

Any idea what I might be doing wrong?

处理txt文件文件夹的方法:

private static void BeginFileProcessing(string sSecretKey_)
{
    DirectoryInfo di = new DirectoryInfo(_sourcePath);
    FileInfo[] files = di.GetFiles(_fileType);

    try
    {
        foreach (FileInfo file in files)
        {
            string thisFileExt = Path.GetExtension(file.Name);
            string thisFileName = Path.GetFileNameWithoutExtension(file.Name);
            string encFileName = String.Format("{0}-enc{1}", thisFileName, thisFileExt);

            if (_TestingOnly)
            {
                Console.Write("Source: " + file.Name + " " + 
                    " Encrypted File: " + encFileName + "\n");
            }

            EncryptFile(file.FullName, _targetPath + encFileName, sSecretKey_);

            if (_DeleteOriginal)
            {
                Console.WriteLine("Deleteing file: " + file.FullName);
                DeleteFile(file.FullName);
            }
        }
    }
    catch (Exception ex)
    {
        LogWriter(string.Format("\nError Decrypting file: {0}", ex), true);
    }
}

加密文件的方法

private static void EncryptFile(string sInputFilename, 
    string sOutputFilename, string sKey)
{
    FileStream fsInput = 
        new FileStream(sInputFilename, FileMode.Open, FileAccess.Read);

    FileStream fsEncrypted = 
        new FileStream(sOutputFilename, FileMode.Create, FileAccess.Write);

    DESCryptoServiceProvider DES = new DESCryptoServiceProvider();

    DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
    DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
    ICryptoTransform desencrypt = DES.CreateEncryptor();

    CryptoStream cryptostream = 
        new CryptoStream(fsEncrypted, desencrypt, CryptoStreamMode.Write);

    try
    {
        byte[] bytearrayinput = System.IO.File.ReadAllBytes(sInputFilename);
        fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
        cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
        cryptostream.Close();
        fsInput.Close();
        fsEncrypted.Close();
    }
    catch (Exception ex)
    {
        string error = "";

        foreach (DictionaryEntry pair in ex.Data)
        {
            error += pair.Key + " = " + pair.Value + "\n";
            Console.WriteLine(error);
        }

        LogWriter(error, true);
    }
} 

删除文件的方法

private static void DeleteFile(string sInputFilename)
{
    try
    {
        if (_TestingOnly)
        {
            Console.WriteLine("TESTING ONLY! File: " + sInputFilename + " would have been deleted.");
        }
        else
        {
            File.Delete(sInputFilename);
        }
    }
    catch (Exception ex)
    {
        Console.Write(ex.ToString());
        LogWriter(ex.ToString(), true);
    }
}

推荐答案

这可能是由于调用EncryptFile后文件没有关闭而引起的.在原始代码中,如果在EncryptFile中遇到了异常,则在调用Close之前发生异常时,流将保持打开状态.使用Using语句使此操作更容易,但是您也可以将Close放在finally块中,如果流不为null,则将其关闭.

This may be caused by your files not being closed after the call to EncryptFile. In your original code, if you hit an exception in EncryptFile the streams would be left open if the exception happens before the call to Close. Using Using statements makes this easier but you can also put the Close in a finally block and close the streams if they're not null.

以下是使用Using的示例:

private static void EncryptFile(string sInputFilename, 
    string sOutputFilename, string sKey)
{
    using(FileStream fsInput =  new FileStream(sInputFilename, FileMode.Open, FileAccess.Read),
            FileStream fsEncrypted = new FileStream(sOutputFilename, FileMode.Create, FileAccess.Write))
    {

        DESCryptoServiceProvider DES = new DESCryptoServiceProvider();

        DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
        DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
        ICryptoTransform desencrypt = DES.CreateEncryptor();

        using(CryptoStream cryptostream = 
            new CryptoStream(fsEncrypted, desencrypt, CryptoStreamMode.Write))
        {
            try
            {
                byte[] bytearrayinput = System.IO.File.ReadAllBytes(sInputFilename);
                fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
                cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
            }
            catch (Exception ex)
            {
                string error = "";

                foreach (DictionaryEntry pair in ex.Data)
                {
                    error += pair.Key + " = " + pair.Value + "\n";
                    Console.WriteLine(error);
                }

                LogWriter(error, true);
            }
        }
    }
}

修改

我建议的代码将解决文件流保持打开状态的问题.但是,问题的根源在于,如果文件很大,系统会在读取文件时抛出OutOfMemoryException.原始代码将读取所有字节,然后再次将字节读取到同一缓冲区中,这既浪费内存,又浪费时间.以下是更正的版本:

My proposed code will solve the issue of the file stream being left open. However, the root of the issue is that the system throws an OutOfMemoryException while reading the file if it's large. The original code would read all the bytes then read the bytes again into the same buffer, which is a waste of memory and a waste of time. Below is a corrected version:

private static void EncryptFile(string sInputFilename, 
    string sOutputFilename, string sKey)
{
    using(FileStream fsInput =  new FileStream(sInputFilename, FileMode.Open, FileAccess.Read),
            fsEncrypted = new FileStream(sOutputFilename, FileMode.Create, FileAccess.Write))
    {

        DESCryptoServiceProvider DES = new DESCryptoServiceProvider();

        DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
        DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
        ICryptoTransform desencrypt = DES.CreateEncryptor();

        using(CryptoStream cryptostream = 
            new CryptoStream(fsEncrypted, desencrypt, CryptoStreamMode.Write))
        {
            byte[] buffer = new byte[2048];
            int readCount = 0;

            try
            {
                while ((readCount = fsInput.Read(buffer, 0, 2048)) > 0)
                {
                    cryptostream.Write(buffer, 0, readCount);
                }
            }
            catch (Exception ex)
            {
                string error = "";

                foreach (DictionaryEntry pair in ex.Data)
                {
                    error += pair.Key + " = " + pair.Value + "\n";
                    Console.WriteLine(error);
                }

                LogWriter(error, true);
            }
        }
    }
}

这篇关于无法通过C#控制台应用程序中的System.IO.File删除某些文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆