C#文件在制作后被锁定

时间:2013-03-21 01:06:38

标签: c# file filestream streamwriter filelock

我正在制作一个Windows服务,部分使用FileStream和StreamWriter创建一个.eml / txt文件,它完美地工作,做我需要做的一切。唯一的问题是它所制作的新文件由于某种原因后来仍然被服务使用,我不知道为什么。任何线索?修复

我认为它必须是与FileStream和StreamWriter相关的线条,因为它们是触及新文件的唯一东西。提前谢谢!

Service1.cs

 public partial class emlService : ServiceBase
{
    Boolean _isRunning;

    public emlService()
    {
        InitializeComponent();
        if (!System.Diagnostics.EventLog.SourceExists("emlServiceSource"))
        {
            System.Diagnostics.EventLog.CreateEventSource(
                "emlServiceSource", "emlServiceLog");
        }
        eventLog1.Source = "emlSerivceSource";
        eventLog1.Log = "emlServiceLog";
    }

    protected override void OnStart(string[] args)
    {
        eventLog1.WriteEntry("In OnStart");
        Thread NewThread = new Thread(new ThreadStart(runProc));
        _isRunning = true;
        //Creates bool to start thread loop
        if (_isRunning)
        {
            NewThread.Start();
        }
    }

    protected override void OnStop()
    {
        eventLog1.WriteEntry("In OnStop");
        _isRunning = false;             
    }

    protected override void OnContinue()
    {

    }

    public void runProc()
    {         

        //Directory of the drop location
        DirectoryInfo drop = new DirectoryInfo(@"C:\inetpub\mailroot\drop");

        //Directory of the pickup location
        string destpath = @"C:\inetpub\mailroot\pickup\";

        //Inits ParserCommands and DropDirectory object
        ParserCommands parserObject = new ParserCommands();

        //Inits array to hold number of messages in drop location
        FileInfo[] listfiles;

        //Inits CFG
        string conf_mailsender = ConfigurationSettings.AppSettings["conf_mailsender"];
        string conf_rcpt = ConfigurationSettings.AppSettings["conf_rcpt"];
        string conf_username_and_password = ConfigurationSettings.AppSettings["conf_username_and_password"];
        string conf_sender = ConfigurationSettings.AppSettings["conf_sender"];
        string conf_raport = ConfigurationSettings.AppSettings["conf_raport"];

        //Loop that never ends
        while (true) 
        {
            Thread.Sleep(1000);
            //Checks if there is a message waiting to be processed and begins processing if so
            listfiles = drop.GetFiles();
            if (listfiles.Length >= 1)
            {
                for (int j = 0; j <= (listfiles.Length - 1); j++)
                {
                    //Gives it time to breathe
                    Thread.Sleep(250);

                    //Gets each line of the original .eml into a string array
                    try
                    {

                        //reader.

                        var lines = File.ReadAllLines(listfiles[j].FullName);
                        string[] linestring = lines.Select(c => c.ToString()).ToArray();

                        //Opens up steam and writer in the new dest, creates new .eml file
                        FileStream fs = new FileStream(destpath + listfiles[j].Name, FileMode.CreateNew);
                        StreamWriter writer = new StreamWriter(fs);

                        //Writes all .eml content into buffer
                        writer.WriteLine("x-sender: " + conf_mailsender);
                        writer.WriteLine("x-receiver: " + conf_rcpt);
                        writer.WriteLine(linestring[2]);
                        writer.WriteLine(linestring[3]);
                        writer.WriteLine(linestring[4]);
                        writer.WriteLine(linestring[5]);
                        writer.WriteLine(linestring[6]);
                        writer.WriteLine(linestring[7]);
                        writer.WriteLine(linestring[8]);
                        writer.WriteLine("From: " + conf_mailsender);
                        writer.WriteLine(linestring[10]);
                        writer.WriteLine("Reply-To: " + conf_mailsender);
                        writer.WriteLine("To: " + conf_rcpt);
                        writer.WriteLine("Subject: " + conf_username_and_password);
                        writer.WriteLine("Return-Path: " + conf_mailsender);
                        writer.WriteLine(linestring[15]);
                        writer.WriteLine();

                        //Seperates start of email from the rest and decode parameter_content
                        string parameter_to = parserObject.getReciever(linestring[12]);
                        string parameter_content = parserObject.DecodeFrom64(linestring[17]);

                        //Creates string ready for base64 encode
                        string encode = "from=" + conf_sender + "&to=" + parameter_to + "&raport=" + conf_raport + "&message=" + parameter_content;

                        //Writes encoded string into buffer
                        writer.WriteLine(parserObject.EncodeTo64(encode));

                        //Writes buffer into .eml file
                        writer.Flush();
                        fs.Flush();

                        fs = null;
                        writer = null;
                        lines = null;
                    }
                        catch (System.IO.IOException e)
                    {
                        Console.WriteLine("no");

                    }

                    //Deletes the file
                    File.Delete(listfiles[j].FullName);
                }

                //Sets the number of files needing sent to 0
                listfiles = null;
            }
        }
    }
}

Program.cs的

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    static void Main()
    {           
        //Starts the Service
        System.ServiceProcess.ServiceBase[] ServicesToRun;
        ServicesToRun = new System.ServiceProcess.ServiceBase[]
            { new emlService() };
        System.ServiceProcess.ServiceBase.Run(ServicesToRun);
    }
}

public class ParserCommands
{
    /// <summary>
    /// Seperates the address before @ from an email address
    /// </summary>
    /// <param name="email"> the email to be split </param>
    /// <returns> everything before @ on an email address </returns>
    public string getReciever(string email)
    {
        string[] Split = email.Split(new Char[] { '@' });
        string Split2 = Split[0];
        char[] chars = { 'T', 'o', ':', ' ' };
        string FinalSplit = Split2.TrimStart(chars);

        return FinalSplit;

    }

    /// <summary>
    /// Decodes base64 into string
    /// </summary>
    /// <param name="encodedData"> the base64 encoded data</param>
    /// <returns>decoded data as string</returns>
    public string DecodeFrom64(string encodedData)
    {
        //Turns into bytes and then turns bytes into string
        byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData);
        string returnValue = System.Text.Encoding.UTF8.GetString(encodedDataAsBytes);

        return returnValue;
    }

    /// <summary>
    /// Decodes base64 data
    /// </summary>
    /// <param name="toEncode"> data that nees to be decoded</param>
    /// <returns> encoded data as string</returns>
    public string EncodeTo64(string toEncode)
    {
        //Turns string into bytes and then encodes it
        byte[] toEncodeAsBytes = System.Text.Encoding.UTF8.GetBytes(toEncode);
        string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);

        return returnValue;
    }
}

3 个答案:

答案 0 :(得分:5)

FileStreamStreamWriterIDisposable,因此您应该将它们包含在using语句中,以确保它们在您完成后关闭。

using (FileStream fs = new FileStream(destpath + listfiles[j].Name, FileMode.CreateNew))
using (StreamWriter writer = new StreamWriter(fs)) {
   // .. your writing code here
}

答案 1 :(得分:5)

来自StreamWriter文档:

  

一个好的做法是在using语句中使用这些对象   非托管资源正确处理。使用声明   当正在使用的代码时,自动调用Dispose对象   它已经完成了。

它们是IDisposable所以应该包含在using中。处理也应该关闭。

答案 2 :(得分:3)

在完成文件写入之后,你有没有关闭文件流?