【问题标题】:String.Contains gives wrong valuesString.Contains 给出了错误的值
【发布时间】:2013-10-31 04:40:34
【问题描述】:

我正在尝试创建一个搜索文件的应用程序,就像 WindowsXP 一样。我正在使用 4 个线程搜索指定目录并打开每个文件以搜索字符串。这是通过从静态类调用静态方法来完成的。然后该方法尝试找出扩展,并根据找到的扩展通过私有方法运行它。我只创造了将纯文本文件读取到班级的可能性。 代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Searcher
{
    static public class Searching 
    {
        static public bool Query(string file, string q)
        {
            file = file.ToLower();

            if (file.EndsWith(".txt")) // plain textfiles
            {
                return txt(file, q);
            } // #####################################
            else if (file.EndsWith(".doc"))
            {
                return false;
            } // #####################################
            else if (file.EndsWith(".dll")) // Ignore these
            {
                return false;
            }
            else if (file.EndsWith(".exe")) // Ignore these
            {
                return false;
            }
            else // will try reading as a textfile
            {
                return txt(file, q);
            }
        }

        static private bool txt(string file, string q)
        {
            string contents;
            TextReader read = new StreamReader(file);
            contents = read.ReadToEnd();
            read.Dispose();
            read.Close();

            return contents.ToLower().Contains(q);
        }

        static private bool docx(string file, string q)
        {
            return false;
        }
    }
}

Query 读取扩展名,然后转发处理。由于此时我只包含纯文本文件,因此无法选择太多。在搜索开始之前,我还告诉我的程序它需要读取所有可能的文件。

现在我的问题出在这里,虽然阅读器只能读取纯文本文件,但它也可以读取图像和应用程序(.exe/.dll)。这是意料之中的,因为它试图读取所有内容。奇怪的是,它返回匹配项。我已经在 Notepad++ 中搜索了文件,但没有匹配项。我还在文件被读入“内容”变量后立即使用断点提取了内容,并尝试搜索该内容,但再次没有匹配。所以这意味着 String.Contains() 方法不能很好地搜索内容,这似乎认为给定的查询在文件中。

我希望有人知道问题可能是什么。我搜索的字符串是“test”,程序在搜索文本文件时工作。

【问题讨论】:

  • 这不会是 string.Contains 中的错误。获取发现意外匹配的文件之一,并在该文件上运行您的程序。在调试器中,查看(可能是二进制)文件的内容在转换为字符串后的样子。那里很可能有与字符串“test”有效匹配的内容。
  • 你怎么知道“test”不在你的exe文件中? exe 文件可以也确实包含字符串
  • 我使用一个文本文件和 2 个 excel 文件测试了您的代码。它工作正常。它没有在 Excel 文件中找到字符串“test”。尝试创建一个空的 Excel 文件并使用它进行测试。
  • 我做到了,但仍然不匹配。从流读取器中,数据进入“内容”字符串,在那里它被转换为小写,然后检查。在应用小写字母后,我提取了数据(字符串格式)。然后我尝试在记事本++中搜索它,发现仍然没有匹配。
  • 如果您使用的是 ASCII 字符,您可以将整个文件或其中的一部分读入字节数组并查找非 ASCII 字符。这不适用于 Unicode 和其他字符表示。那么你很可能会识别出非文本文件。

标签: c# windows file-search


【解决方案1】:

很高兴您找到了解决方案。

我仍然希望能够查看一些有问题的“误报”文件。

与此同时,有点切题但仍然相关,我会将您的 txt 函数更改为:

private bool txt(string file, string q)
{
    string contents = "";
    using (TextReader read = new StreamReader(file))
    {
        contents = read.ReadToEnd();
    }

    return contents.ToLower().Contains(q);
}

这样更干净。

编辑:
好吧,它们返回 true 的原因是因为这些文件中确实包含字符串“Test”,特别是:MSI 和 [OnUpda teSt 中的 [CCP_TEST RMCCPSearchValidateProductIDSetODBCFoldersAllocateRegistrySpaceNOT] >环]在dll。所以,String.Contains() 工作正常。

所以,回到过滤您要搜索的内容。要么给出一个已知文本结尾的列表,要么让用户选择他想要的。

您可能要考虑的其他一些事情只是搜索确切的单词,因此testOnUpdateString 的情况下将不正确:)

文本扩展:wikifileinfo

【讨论】:

【解决方案2】:

我尝试了一个 .Dll 和 exe 文件,对我来说效果很好。您正在变得真实,因为您正在搜索的值存在于文件中。尝试用记事本打开文件并搜索值。

也尝试搜索一些其他字符串,例如“eafrd”而不是 test(这是一个可以出现在 dll 或 exe 文件中的字典单词)。它返回错误。

还可以查看您在记事本中打开的文件中的任何随机单词尝试搜索它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-02-02
    • 2018-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多