Engodel
Engodel

Reputation: 64

How to recurse effeciently through a large amount of file (1 mill +)

I am trying to build a web application that will allow the end user to select a specific date and file type and delete all types of that file before the selected date on a selected NAS. The problem is that some of the NAS’s can have up to 39TB worth of data which by the time my code tries enumerate all these file my web page will have timed out.

I have tried to use a background worker to help, but this seemed to make no difference. If someone could take a look at the code below and maybe point me in a better direction that would be great.

 <div class="PanelColour">
        <div class="auto-style3">
            <img src="Images/MainLogo.jpg" class="auto-style3" />
        </div>

        <div>
            <span class="heading">Select a Nas    </span>
            <div>
            </div>
            <asp:DropDownList ID="DropDownList1" runat="server" CssClass="MainText" Width="230px" AutoPostBack="True">
                <asp:ListItem Text="dubfilm01-nas" Value="1"></asp:ListItem>
                <asp:ListItem Text="dubfilm02-nas" Value="2"></asp:ListItem>
                <asp:ListItem Text="dubfilm03-nas" Value="3"></asp:ListItem>
                <asp:ListItem Text="dubfilm04-nas" Value="4"></asp:ListItem>
                <asp:ListItem Text="dubfilm05-nas" Value="5"></asp:ListItem>
                <asp:ListItem Text="dubfilm06-nas" Value="6"></asp:ListItem>
                <asp:ListItem Text="dubfilm07-nas" Value="7"></asp:ListItem>
                <asp:ListItem Text="dubfilm08-nas" Value="8"></asp:ListItem>
                <asp:ListItem Text="dubfilm09-nas" Value="9"></asp:ListItem>
                <asp:ListItem Text="dubfilm10-nas" Value="10"></asp:ListItem>
                <asp:ListItem Text="dubfilm11-nas" Value="11"></asp:ListItem>
                <asp:ListItem Text="dubfilm12-nas" Value="12"></asp:ListItem>
                <asp:ListItem Text="dubfilm13-nas" Value="13"></asp:ListItem>
                <asp:ListItem Text="dubfilm14-nas" Value="14"></asp:ListItem>
                <asp:ListItem Text="dubfilm15-nas" Value="15"></asp:ListItem>
                <asp:ListItem Text="dubfilm16-nas" Value="16"></asp:ListItem>
                <asp:ListItem Text="dubfilm17-nas" Value="17"></asp:ListItem>
                <asp:ListItem Text="dubfilm18-nas" Value="18"></asp:ListItem>
                <asp:ListItem Text="dubfilm19-nas" Value="19"></asp:ListItem>
                <asp:ListItem Text="dubfilm20-nas2" Value="20"></asp:ListItem>
                <asp:ListItem Text="dubfilm21-nas2" Value="21"></asp:ListItem>
                <asp:ListItem Text="dubfilm22-nas2" Value="22"></asp:ListItem>
                <asp:ListItem Text="dubfilm23-nas2" Value="23"></asp:ListItem>
                <asp:ListItem Text="dubfilm24-nas" Value="24"></asp:ListItem>
                <asp:ListItem Text="dubfilm25-nas" Value="25"></asp:ListItem>
                <asp:ListItem Text="dubfilm26-nas" Value="26"></asp:ListItem>
                <asp:ListItem Text="Select a Nas" Value="27" Selected="True"></asp:ListItem>



            </asp:DropDownList>

            <div class="auto-style4">
                <table class="auto-style6">
                    <tr class="subheading">
                        <th class="auto-style5">Select files to delete</th>
                        <th class="auto-style7">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Select date to delete from</th>

                    </tr>
                    <tr>
                        <td class="auto-style5">
                            <asp:CheckBoxList ID="CheckBoxList1" runat="server" Width="203px" Height="184px">
                                <asp:ListItem Text=" Image files " Value="jpeg" class="MainText"></asp:ListItem>
                                <asp:ListItem Text=" Text files " Value="jpeg" class="MainText"></asp:ListItem>
                                <asp:ListItem Text=" All files " Value="jpeg" class="MainText"></asp:ListItem>


                            </asp:CheckBoxList>
                        </td>
                        <td class="auto-style7">

                            <asp:Calendar ID="Calendar1" runat="server" BackColor="White" BorderColor="White" BorderWidth="1px" Font-Names="Verdana" Font-Size="10pt" ForeColor="Black" Height="196px" Width="488px" CssClass="MainText" NextPrevFormat="FullMonth">
                                <DayHeaderStyle Font-Bold="True" Font-Size="11pt" />
                                <NextPrevStyle Font-Size="8pt" ForeColor="#333333" Font-Bold="True" VerticalAlign="Bottom" />
                                <OtherMonthDayStyle ForeColor="#999999" />
                                <SelectedDayStyle BackColor="#333399" ForeColor="White" />
                                <TitleStyle BackColor="White" BorderColor="Black" BorderWidth="4px" Font-Bold="True" Font-Size="12pt" ForeColor="#333399" />
                                <TodayDayStyle BackColor="#CCCCCC" />
                            </asp:Calendar>

                        </td>
                        <td class="auto-style8">
                            <asp:Button ID="Button2" runat="server" Text="Delete " CssClass="buttonBL" OnClick="Button2_Click" Width="98px" />
                        </td>


                    </tr>
                </table>
            </div>












            <div>
            </div>
            <br />
            <div>



                <asp:Button ID="Button1" runat="server" Text="Navigate to Folder" Class="buttonBL" Height="57px" OnClick="Button1_Click" Width="161px" />
                &nbsp&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp 


             <asp:TextBox ID="TextBox1" runat="server" Height="51px" Width="787px" CssClass="MainText"></asp:TextBox>


            </div>



            </tr>




            <br />





        </div>
</form>

and the c# code behind this looks like this

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Trinet.Networking;

public partial class Admin : System.Web.UI.Page
{
    private static BackgroundWorker worker = new BackgroundWorker();
    private event EventHandler BackgroundWorkFinished;
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!this.IsPostBack)
        {
            worker.DoWork += worker_DoWork;
            worker.RunWorkerCompleted += worker_RunWorkerCompleted;
            worker.ProgressChanged += worker_ProgressChanged;
            worker.WorkerReportsProgress = true;
            worker.WorkerSupportsCancellation = true;
        }
    }
protected void Button2_Click(object sender, EventArgs e)
{
    DateTime d2 = Calendar1.SelectedDate;
    string nas = DropDownList1.SelectedItem.Text;
    object[] args = { d2, nas };
    if (worker.IsBusy != true)
    {
        worker.RunWorkerAsync(args);
    }

}
protected void Button1_Click(object sender, EventArgs e)
{
    try
    {

        System.Diagnostics.Process process = new System.Diagnostics.Process();
        System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
        startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
        startInfo.FileName = "cmd.exe";
        string _path = "\\\\" + DropDownList1.SelectedItem.Text;
        startInfo.Arguments = string.Format("/C start {0}", _path);
        process.StartInfo = startInfo;
        process.Start();
    }

    catch
    {

    }

}
private int Getfilesdate(DateTime d2)
{
    try
    {
        DateTime d1 = DateTime.Now;
       // DateTime d2 = Calendar1.SelectedDate;
        TimeSpan t = d1 - d2;
        int NrOfDays = Convert.ToInt16(t.TotalDays);
        return (NrOfDays);
    }
    catch
    {
        return 0;
    }
}
private void getfiles(int days,string path)
{
    uncpath(path, days);
}
private string uncpath(string server, int days)

{

    string nas = server;
    string SI = "";
    ShareCollection shi = ShareCollection.LocalShares;
    if (server != null && server.Trim().Length > 0)
    {
        shi = ShareCollection.GetShares(server);
        if (shi != null)
        {
            foreach (Share si in shi)
            {
                deletefiles(si.ToString(), days);

            }
            return "";
        }
    }

    return "";
}
private void deletefiles(string path, int days)
{
    try
    {

      //  int nofiles = Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories)
      // .Where(s => s.ToLower().EndsWith(".tiff") || s.ToLower().EndsWith(".jpg")).Count();

        TextBox1.Text = string.Empty;
    //    TextBox1.Text = "There are "+nofiles + " in all directories";
        int i = 1;
        worker.ReportProgress(i);

        var files = Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories)
       .Where(s => s.ToLower().EndsWith(".tiff") || s.ToLower().EndsWith(".jpg"));

        foreach (string file in files)
        {
            FileInfo info = new FileInfo(file);
            if (info.LastWriteTime < DateTime.Now.AddDays(-days))
            {

               File.Delete(file);

            }
        }

    }
    catch
    {

    }
}

private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{

    int i = Convert.ToInt16( e.ProgressPercentage);
    if (i == 0)
        {
        TextBox1.Text = "Gathering file information.................";
        }
    else
    {

        TextBox1.Text = "..............This may take a while, grab a cup of coffee";
    }
}

private void worker_DoWork(object sender, DoWorkEventArgs e)
{
    Object[] arg = e.Argument as Object[];
    string path = (string)arg[1];
    DateTime d2 = (DateTime)Convert.ToDateTime(arg[0]);
    int i = 0;
    worker.ReportProgress(i);
    int NrofDays = Getfilesdate(d2);
    getfiles(NrofDays,path);
}

private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    TextBox1.Text = string.Empty;
    TextBox1.Text = "Completed";
}
}

I would really appreciate some help

Thanks

Upvotes: 1

Views: 75

Answers (1)

CodeCaster
CodeCaster

Reputation: 151674

Enumerating files is a relatively slow operation, even more so over a network.

I would keep a copy of the file information in a database that you schedule to regularly update, for example in a Windows Service or Hangfire job.

Then you can show the file information from the database, with the additional bonus of indexing (faster search) and pagination (faster response times for your web pages).

Upvotes: 2

Related Questions