2

我有将 SQL 转换为 CSV 的代码:

public void CreateCSVFile(DataTable dt, string strFilePath, bool Is_Ordre, int TypeDonne)
{

    //FileStream fs = new FileStream(strFilePath, FileMode.Create);
    // FileStream fs = File.Create(strFilePath);

    // Create the CSV file to which grid data will be exported.
    //StreamWriter sw = new StreamWriter(fs);
    //StreamWriter sw = new StreamWriter(strFilePath, false);
    using (var sw = new StreamWriter(strFilePath, false))
    {
        // First we will write the headers.
        //DataTable dt = m_dsProducts.Tables[0];
        int iColCount = dt.Columns.Count;
        for (int i = 0; i < iColCount; i++)
        {
            sw.Write(dt.Columns[i]);
            if (i < iColCount - 1)
            {
                sw.Write(",");
            }
        }
        if (Is_Ordre) sw.Write(", TYP_DONNE");

        sw.Write(sw.NewLine);

        // Now write all the rows.
        foreach (DataRow dr in dt.Rows)
        {
            for (int i = 0; i < iColCount; i++)
            {
                if (!Convert.IsDBNull(dr[i]))
                {
                    sw.Write("\'" + dr[i].ToString().Replace("'", " ").Replace(",", ".") + "\'");
                }
                else
                {
                    sw.Write("\' \'");
                }
                if (i < iColCount - 1)
                {
                    sw.Write(",");
                }
            }
            if (Is_Ordre) sw.Write(", \'" + TypeDonne + "\'");
            sw.Write(sw.NewLine);
        }                
        sw.Flush();
        sw.Close();
        sw.Dispose();
    }
        //fs.Close();

}

之后,我通过电子邮件发送 CSV 文件:

Attachment data_OD = new Attachment(LeSource, MediaTypeNames.Application.Octet);
Attachment data_LV = new Attachment(LeSource_LV, MediaTypeNames.Application.Octet);
oEmail.SendingEmail(ClientID,  data_OD, data_LV);

public void SendingEmail(string CodeClient, Attachment dataOD, Attachment dataLV)
{
    try
    {
        Pers_Conf oConf = LeConf.Get_Config(CodeClient);

        MailMessage omail = new MailMessage();
        var oSmtp = new SmtpClient("smtp.gmail.com", 587)
        {
            Credentials = new NetworkCredential("xxxxxx@gmail.com", "xxxxxx"),
            EnableSsl = true
        };

        omail.From = new MailAddress("xxxxx@gmail.com");               
        omail.To.Add(oConf.EmailAddr);
        omail.Subject = "xxxxxx_" + CodeClient;
        omail.Body = CodeClient;

        omail.Attachments.Add(dataOD);
        omail.Attachments.Add(dataLV);

        oSmtp.Send(omail);
    }
    catch (Exception excThrown)
    {
        throw excThrown;
    }

似乎StreamWriter没有正确关闭文件,我已经尝试过:

    Try
    {
    StreamWriter sw = new StreamWriter(strFilePath, false);
    }
    Catch
    {
    }
    Finaly
    {
     sw.Flush();
     sw.Close();
     sw.Dispose();
}

但在finally块中它不识别sw

任何的想法 ?

PS:这行代码抛出一个异常,告诉其他进程正在使用该文件

 using (var sw = new StreamWriter(strFilePath, false))

没有关闭是因为StreamWriter没有正确关闭还是因为发送电子邮件正在使用这个文件?

4

5 回答 5

1

Supposing you enter in this code more than one time.
In either case you need to call the MailMsg.Dispose() of the MailMessage class. Otherwise, it will hold the attachment resulting in a file locked the next time you try to write in it.

Try to use the using statement also on the MailMessage

        try 
        { 
            Pers_Conf oConf = LeConf.Get_Config(CodeClient); 

            using(MailMessage omail = new MailMessage())
            {
                .....
                oSmtp.Send(omail); 
            }
        } 
        catch (Exception excThrown) 
        { 
            throw excThrown; 
        } 
于 2012-08-23T08:35:32.203 回答
0

那是因为您StreamWriter的声明超出范围,请尝试以下操作:

using (StreamWriter sw = new StreamWriter(strFilePath, false))
{
}

这将在编译时为您添加try和代码。finally或者,如果您想自己指定try块,请执行以下操作:

StreamWriter sw;

try
{
    sw = new StreamWriter(strFilePath, false);
}
catch
{
}
finally
{
    sw.Flush();
    sw.Close();
    sw.Dispose();        
}

This will give it scope to the finally.

EDIT

You could try adding using blocks to your file stream to create your file, and then write to this stream with StreamWriter as you're kind of already doing, as Darin points out.

using (FileStream fs = new FileStream(strFilePath, FileMode.Create, FileAccess.Write))
{
    using (StreamWriter sw = new StreamWriter(fs))
    {
        // write your content

        sw.Flush();
        sw.Close();
    }

    fs.Close();
}

If you're creating your file using File.Create as it seems in your code (but it's commented out) then you're not closing your FileStream so this may be a factor.

于 2012-08-23T08:21:09.957 回答
0

The StreamWriter will be out of scope. If you refractor to the following...

StreamWriter sw;
try
{
   sw = new StreamWriter(strFilePath, false);
}
Catch
{

}
finally
{
 sw.Flush();
 sw.Close();
 sw.Dispose();
}
于 2012-08-23T08:23:09.913 回答
0

In your last block of code sw is not recognized because it is out of scope.

Please try this:

 StreamWriter sw;

 try
 {
    sw = new StreamWriter(strFilePath, false);
 }
 catch
 {
    // Never do an empty catch BTW!    
 }
 finally
 {
   if (sw != null)
   {
     sw.Flush();
     sw.Close();
     sw.Dispose();
   }
}

or better yet, use a using statement:

using (StreamWriter sw = new StreamWriter(strFilePath, false))
{
    // Just do your thing, at the end sw will be cleaned up for you :)
}
于 2012-08-23T08:23:14.803 回答
0

So, it looks like your first attemopt was reasonable (in summary below)

using (var sw = new StreamWriter(strFilePath, false)) 
{ 
    sw.Flush();  
    sw.Close();  
    sw.Dispose();  
}

Though sw..Dispose() not needed as it is in a using{} block.

So what exactly was the problem you were seeing?

Ok, I have just seen your edit. Are you sure it is not something else locking the file, possibly the Attachment. I cannot see what scope this is being declared in, but is it possible that it is hanging on to the file? If you want to check what is locking it you can use ProcessMonitor...

http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx

于 2012-08-23T08:28:20.960 回答