简体   繁体   中英

How to prevent empty file from being created

I have a file that is being created based on the items in a Repeater control if the radioButton for each item is "Yes". My issue that if the file is empty, it is still being created. I have tried FileName.Length > 0 and other possible solutions but I get errors that the file can not be found. I am sure the issue is within my logic but I cant see where. Any ideas?

protected void btnContinue_Click(object sender, EventArgs e)
{
    string JobName;
    string FileName;

    StreamWriter sw;
    string Name, Company, Date;

    JobName = TYest + "_" + System.DateTime.Now;
    JobName = JobName.Replace(":", "").Replace("/", "").Replace(" ", "");
    FileName = JobName + ".txt";

    sw = new StreamWriter(C: +"/" + FileName, false, Encoding.GetEncoding(1250));

    foreach ( RepeaterItem rpItems in rpGetData.Items )
    {
        RadioButtonList rbYesNo = (RadioButtonList)rpItems.FindControl("rbBadge");

        if ( rbYesNo.SelectedItem.Text == "Yes" )
        {
            Label rName = (Label)rpItems.FindControl("lblName");
            Label rCompany = (Label)rpItems.FindControl("lblCompany");
            Label rFacilityName = (Label)rpItems.FindControl("lblFacility_Hidden");
            Name = rName.Text;
            Company = rCompany.Text;
            Date = System.DateTime.Now.ToString("MM/dd/yyyy");

            sw.WriteLine("Name," + Name);
            sw.WriteLine("Company," + Company);
            sw.WriteLine("Date," + Date);
            sw.WriteLine("*PRINTLABEL");
        }

        sw.Flush();
        sw.Dispose();

        if ( File.Exists("C:/" + FileName) )
        {
            try
            {
                File.Copy(+"C:/" + FileName, LoftwareDropPath + FileName, true);
            }
            catch ( Exception ex )
            {
                string msgE = "Error";
                msgE += ex.Message;
                throw new Exception(msgE);
            }
        }
        else
        {
            //Do something if temp file not created properly
            lblMessage.Text = "An error has occurred. Plese see your host to get a printed name badge.";
        }

        MessageBox messageBox = new MessageBox();
        messageBox.MessageTitle = "Printed?";
        messageBox.MessageText = "If not, please see host.";
        Literal1.Text = messageBox.Show(this);
    }
}

sounds like you want to detect if a file is empty. Use:

long length = new System.IO.FileInfo(path).Length;
if(length == 0)....

FileName.Length just tells you how long the file name is - not usefule

Why not check if the file exists first? That should solve your exception problems! If you want to know if the file is empty I would recommend checking what you're writing to the file and making sure it's not all empty and THEN write to the file if you actually have content?

if(File.Exists(File))
{
    if(new FileInfo(File).Length > 0)
    {
         //Do Stuff.
    }
}

You should change it to only write and create the file when you have some data to write.

A simple way of doing this is to store everything memory with something like a StringBuilder , then afterwards write the contents of the string builder to the file if there is something to write:

var sb = new StringBuilder();

foreach (RepeaterItem rpItems in rpGetData.Items)
{
    RadioButtonList rbYesNo = (RadioButtonList)rpItems.FindControl("rbBadge");

    if (rbYesNo.SelectedItem.Text == "Yes")
    {
        // ..omitted..

        sb.AppendLine("Name," + Name);
        sb.AppendLine("Company," + Company);
        sb.AppendLine("Date," + Date);
        sb.AppendLine("*PRINTLABEL");
    }
}

if (sb.Length > 0)
{
    File.WriteAllText(FileName, sb.ToString(), Encoding.GetEncoding(1250));
}

How about this:

StreamWriter sw = null;
string Name, Company,  Date;   

JobName = TYest + "_" + System.DateTime.Now;
JobName = JobName.Replace(":", "").Replace("/", "").Replace(" ", "");
FileName = @"C:\" + JobName + ".txt";
try
{
 foreach (RepeaterItem rpItems in rpGetData.Items)
 {

     RadioButtonList rbYesNo = (RadioButtonList)rpItems.FindControl("rbBadge");

      if (rbYesNo.SelectedItem.Text == "Yes")
       {
           if (null == sw)
               sw = new StreamWriter(FileName, false, Encoding.GetEncoding(1250));
           Label rName = (Label)rpItems.FindControl("lblName");
           Label rCompany = (Label)rpItems.FindControl("lblCompany");
           Label rFacilityName = (Label)rpItems.FindControl("lblFacility_Hidden");
           Name = rName.Text;
           Company = rCompany.Text;
           Date = System.DateTime.Now.ToString("MM/dd/yyyy");

           sw.WriteLine("Name," + Name);
           sw.WriteLine("Company," + Company);
           sw.WriteLine("Date," + Date);
           sw.WriteLine("*PRINTLABEL");
  }
}
finally
{
    if (null != sw)
    {
        sw.Flush();
        sw.Dispose();
    }
}

Build your FileName completely once so that you know it is always the same. Then only create your StreamWriter if something is going to be written. Also, use a try..finally to make sure your code to free your resources is always hit.

You can check whether any items are eligible for saving before opening the stream writer like this:

var itemsToBeSaved = rpGetData.Items
    Where(ri => ((RadioButtonList)ri.FindControl("rbBadge")).SelectedItem.Text == "Yes");

if (itemsToBeSaved.Any()) {
    string path = @"C:\" + FileName;
    using (var sw = new StreamWriter(path, false, Encoding.GetEncoding(1250))) {
        foreach (RepeaterItem rpItems in itemsToBeSaved) {
            Label rName = (Label)rpItems.FindControl("lblName");
            Label rCompany = (Label)rpItems.FindControl("lblCompany");
            Label rFacilityName = (Label)rpItems.FindControl("lblFacility_Hidden");
            Name = rName.Text;
            Company = rCompany.Text;
            Date = System.DateTime.Now.ToString("MM/dd/yyyy");

            sw.WriteLine("Name," + Name);
            sw.WriteLine("Company," + Company);
            sw.WriteLine("Date," + Date);
            sw.WriteLine("*PRINTLABEL");
        }
    } // Flushes, Closes und Disposes the stream automatically.
}

The first statement prepares a filtered enumeration of repeater items containing only the ones to be saved. itemsToBeSaved.Any() tests if this enumeration contains at least one item. This enumeration is then reused in the foreach statement. Therefore it is not necessary to check the conditions again.

The using statement takes care of closing the stream in all situations, even if an exception should occur while writing to the file. I also declared the stream writer in the using statement. Therefore you can delete your declaration StreamWriter sw = null; .

Also note the expression @"C:\\" + FileName . The @ makes the string constant a verbatim string. This means that the usual escape character '\\' loses its meaning and is used as is . Path.Combine(...) does not work here, since it does not add the path separator after a drive letter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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