问题描述
我正在加密一些文本文件.加密文件后工作正常,但是有时我在尝试删除原始未加密文件时收到此错误:
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:
这似乎在大型文本文件上发生. (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删除某些文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!