C# is there a limit to number of selected files in

2019-02-25 10:46发布

问题:

I've got a C# windows forms application where I load XML files and CGM graphics files into my application from an Open File browser. I seem to be able to select a couple of hundred at a time and it works without fault, but any more and a dialog box pops up telling me it can't find file such and such, but only gives half the file name. I'm assuming this is due to a limit on the amount of files that can be selected / processed in one go through the open file dialog.

Does anybody know what that number is, and is there a way around it if i have more than that limit to select at once?

I'm effectively 'importing' the files into my application, whereby using a foreach loop the selected files get moved to another folder, and the application writes to an XML file with all the file names of the files imported (as well as other data on the files).

Below is the entire 'import' method

private void addFilesToCSDBToolStripMenuItem_Click(object sender, EventArgs e)
{
    int DMsimported = 0;
    int graphicsImported = 0;

    if (projectName == "")
    {
        MessageBox.Show("Please open a project first", "DAWS");
        return;
    }

    DialogResult result = openFileDialog1.ShowDialog();
    if (result == DialogResult.OK)
    {
        MessageBox.Show("This process may take several minutes depending on the number of imports", "DAWS");
        Application.UseWaitCursor = true;

        foreach (string file in openFileDialog1.FileNames)
        {
            string fileName = Path.GetFileNameWithoutExtension(file); //Gets just the name from the file path
            string ext = Path.GetExtension(file.ToLower());

            if (ext != ".CGM" && ext != ".cgm")
            {
                    bool exists = xmlFileWriter.checkIfFIleExists(fileName + ext);

                    if (exists != true)
                    {
                        xmlFileWriter.writeDatatoXML(file);
                        File.Move(file, CSDBpath + projectName + "\\CheckedIN\\" + fileName + ext);
                        DMsimported = DMsimported + 1;
                    }
                    else
                    {
                        MessageBox.Show(fileName + " already exists in the CSDB. This file will be skipped.", "DAWS");
                    }  
                }
            else
            {
                if (File.Exists(CSDBpath + projectName + "\\Graphics\\" + fileName + ext))
                {
                    if (Properties.Settings.Default.OverwriteGraphics == true)
                    {
                        File.SetAttributes(CSDBpath + projectName + "\\Graphics\\" + fileName + ext, FileAttributes.Normal); // need this line in order to set the file attributes. Exception thrown otherwise when system tries to overwrite the file.
                        File.Delete(CSDBpath + projectName + "\\Graphics\\" + fileName + ext);
                        File.Copy(file, CSDBpath + projectName + "\\Graphics\\" + fileName  + ext); //need to give the option as to whether to delete the existing file or skipp.
                    }
                    else
                    {
                        MessageBox.Show(fileName + " already exists in the CSDB. This file will be skipped. To enable overwriting tick the checkbox in Preferences", "DAWS");
                    }
                }
                else
                {
                    File.Copy(file, CSDBpath + projectName + "\\Graphics\\" + fileName + ext);
                }

                graphicsImported = graphicsImported + 1;                            
            }   
        }

        Application.UseWaitCursor = false;

        buildAllListViews();
        copyCGMfilesToDirectories();

        if (DMsimported > 0)
        {
            MessageBox.Show(DMsimported.ToString() + " DM files successfully imported into the CSDB", "DAWS");
        }
        if (graphicsImported > 0)
        {
            MessageBox.Show(graphicsImported.ToString() + " graphic files successfully imported into the CSDB", "DAWS");
        }
        if (graphicsImported == 0 && DMsimported == 0)
        {
            MessageBox.Show("No files imported", "DAWS");
        }

        updateMainFilesList();  
    }  
}

回答1:

According to this article, you will receive a "Too many files selected" error message when you use the OpenFileDialog control to select more than 200 files.



回答2:

Just tested in .NET 4.5, no problem with 5000 files, so it looks like it depends on .net framework/os version (I've used long enough file names, just to be sure, that it does not depend on some old windows constraint, like max length of all file names is 65536 or 32768):

var directory = @"c:\test\test";
Directory.CreateDirectory(directory);

for (int i = 0; i < 5000; i++)
{
    var path = Path.Combine(directory, i.ToString() + new string('a', 200));
    File.WriteAllText(path, "");
}

if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
    var fileCount = openFileDialog1.FileNames;
    var lastFileName = openFileDialog1.FileNames[4999];
}


回答3:

In .NET Framework 1.1, for the OpenFileDialog.Multiselect Property:

There is a hard-coded limit of 200 files that can be opened with the Open File dialog box. For more information about this limitation, see article 820631, "PRB: 'Too Many Files Selected' Error Message Occurs When You Use the OpenFileDialog Control", in the Microsoft Knowledge Base at http://support.microsoft.com.

When you have to work with such a large number of files, maybe it makes more sense to select only the folder (even more reasonable if you select all the files in the folder, if this is your case). Try using the FolderBrowserDialog Class:

var folderBrowserDialog = new FolderBrowserDialog();
if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
{
    var fi = new DirectoryInfo(folderBrowserDialog.SelectedPath);
    // here you get the files collection
    var files = fi.GetFiles();
}


回答4:

Try:

   if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
    openFileDialog1.Multiselect = false;
    var fileCount = openFileDialog1.FileNames;
    var lastFileName = openFileDialog1.FileNames[4999];
}