【问题标题】:ZipArchive search to listview C#ZipArchive 搜索到列表视图 C#
【发布时间】:2015-08-12 23:46:47
【问题描述】:

我是 C# 新手 我正在尝试将搜索结果从文本框显示到 button_click 上的列表视图。

这是我的代码:

private void button1_Click(object sender, EventArgs e)
{
    listView1.Items.Clear();
    listView1.Refresh();
    string[] filePaths = Directory.GetFiles(@textBox1.Text, "*.zip");
    string txtSearch = textBox2.Text;

    foreach (var filePath in filePaths)
    {
        using (ZipArchive archive = ZipFile.OpenRead(filePath))
        {
            foreach (ZipArchiveEntry entry in archive.Entries)
            {
                var position = entry.Name.IndexOf(
                    txtSearch,                                             
                    StringComparison.InvariantCultureIgnoreCase);

                if (position > -1)
                {
                    listView1.Items.Add(entry.Name);
                }
                else
                {
                    MessageBox.Show(
                        "FILE NOT FOUND", 
                        "ERROR", 
                        MessageBoxButtons.OK, 
                        MessageBoxIcon.Error);
                }
            }
        }
    }
}'

如果它的单个文件夹包含其他档案但具有以下文件夹结构,则此代码有效: 文件夹A(包含):文件夹A1,文件夹A2。 FloderA1(包含):、FolderA1.1、FolderA1.2、FolderA1.3 和 FolderA1.4 FloderA1.1 到 1.4(每个包含): , 文件夹和大量档案(.zip 和 .rar) FloderA2(包含):FolderA2.1、FolderA2.2 和 FolderA2.3。 FloderA2.1 到 2.3(每个都包含):很多档案(.zip 和 .rar)

即使任何文件夹=文件路径,我如何使用此代码搜索具有特定扩展名的文件以列出。

提前致谢。

【问题讨论】:

  • 我可以建议一个显示文件名的信息更丰富的错误消息吗?它可能会有所帮助。
  • 这不再是原来的问题。您的更新使这些答案变得毫无意义。

标签: c# ziparchive


【解决方案1】:

您被告知 4 次的原因可能是因为您正在加载的 Zip 文件中有 4 个项目不符合 txtSearch 标准。由于您在内部 foreach 循环中有消息框,因此每次在 ZipArchiveEntry 中找不到文件时,都会显示消息框。

您可以将消息框移到外循环,以便每个 .zip 文件仅显示一次。当您使用它时,您可以使用 Lambda 来简化代码,从而无需辅助 foreach 循环。 Where 子句将过滤掉ZipArchive.Entries 集合,然后通过.Select'ing 集合中每个项目的Name 属性将结果集转换为字符串集合。

private void button1_Click(object sender, EventArgs e)
{
    listView1.Items.Clear();
    listView1.Refresh();
    string[] filePaths = Directory.GetFiles(@textBox1.Text, "*.zip");
    string txtSearch = textBox2.Text;
    var foundEntries = new List<string>();

    foreach (var filePath in filePaths)
    {
        using (ZipArchive archive = ZipFile.OpenRead(filePath))
        {
            foundEntries = archive.Entries
                .Where(e => e.Name.IndexOf(txtSearch, StringComparison.InvariantCultureIgnoreCase) >= 0)
                .Select(e => e.Name);
            if (foundEntries.Any())
            {
                listView1.Items.AddRange(foundEntries);
            }
            else
            {
                MessageBox.Show("FILE NOT FOUND", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        foundEntries.Clear();
    }
}

【讨论】:

  • 3 来自此的错误:错误 1 ​​无法在此范围内声明名为“e”的局部变量,因为它会给“e”赋予不同的含义,而“e”已在“父级或当前级”中使用' 范围来表示其他东西。错误 2 'System.Windows.Forms.ListView.ListViewItemCollection.AddRange(System.Windows.Forms.ListView.ListViewItemCollection)' 的最佳重载方法匹配有一些无效参数错误 3 参数 1:无法从 'System.Collections.Generic 转换.List' 到 'System.Windows.Forms.ListView.ListViewItemCollection'
  • 那是因为您使用的是 ListViewCollection。您的问题应该更清楚您正在使用什么类型。您的问题说您使用的是ListView,它确实有一个AddRange。您需要对用作ListCollectionView 源的集合执行AddRange。然后刷新您的ListCollectionView。至于第一个错误,这很奇怪。您应该能够在每个 Linq lambda 中嵌套相同的变量名。解决这个问题的简单方法就是重命名变量。
【解决方案2】:

如果名称不包含指定的字符串,将为每个 zip 文件中的每个存档显示该 MessageBox。 我猜您希望只显示一次消息,以防所有 zip 文件都不包含任何名称包含指定字符串的文件。

private void button1_Click(object sender, EventArgs e)
{
    listView1.Items.Clear();
    listView1.Refresh();
    string[] filePaths = Directory.GetFiles(@textBox1.Text, "*.zip");
    string txtSearch = textBox2.Text;

    bool found = false;
    foreach (var filePath in filePaths)
    {
        using (ZipArchive archive = ZipFile.OpenRead(filePath))
        {
            foreach (ZipArchiveEntry entry in archive.Entries)
            {
                var position = entry.Name.IndexOf(txtSearch, StringComparison.InvariantCultureIgnoreCase);
                if (position > -1)
                {
                    found = true;
                    listView1.Items.Add(entry.Name);
                    break;      // Comment out this line if you want more results from a single zip file
                }
            }
        }
    }
    if (!found)
    {
        MessageBox.Show("File not found", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

【讨论】:

  • 感谢您的回复。此解决方案使其冻结而不显示任何错误消息。我试图迭代的文件夹是性质的:
【解决方案3】:

看,我点击了 4 次,因为“找不到文件”发生了 4 次,每次都显示一个消息框。我认为您应该在代码中进行一些更改:

foreach (var filePath in filePaths)
    {
        int count=0;
        using (ZipArchive archive = ZipFile.OpenRead(filePath))
        {
            foreach (ZipArchiveEntry entry in archive.Entries)
            {
                var position = entry.Name.IndexOf(txtSearch, StringComparison.InvariantCultureIgnoreCase);
                if (position > -1)
                {
                    listView1.Items.Add(entry.Name);
                    count++;
                }

            }
            if(count==0)
            {
                 MessageBox.Show("FILE "+filepath+ "NOT FOUND", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }

更新

要获取文件夹及其子文件夹中的所有文件,请阅读此内容以及 thisthisthis

【讨论】:

  • I get invaliddataexception washandled error: End Of Central Directory 中预期的条目数不对应
  • 好吧,上面的代码应该和原来的逻辑没有任何关系。它只是简单地为 filePaths 数组中的每个循环添加一个“计数”变量。你的旧代码现在有同样的问题吗?
猜你喜欢
  • 2019-02-11
  • 1970-01-01
  • 1970-01-01
  • 2011-04-02
  • 2011-07-13
  • 1970-01-01
  • 1970-01-01
  • 2015-08-05
  • 1970-01-01
相关资源
最近更新 更多