栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

数千个文件中的模式匹配

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

数千个文件中的模式匹配

本机工具可以更快地处理此类文本文件的主要原因是它们假定一个特定的字符集,尤其是当它具有基于ASCII的8位编码,而Java执行字节到字符的转换时,其抽象能力可以支持任意字符集。

当我们类似地假设具有上述属性的单个字符集时,我们可以使用低级工具,这些工具可能会大大提高性能。

对于此类操作,我们定义了以下辅助方法:

private static char[] getTable(Charset cs) {    if(cs.newEnprer().maxBytesPerChar() != 1f)        throw new UnsupportedOperationException("Not an 8 bit charset");    byte[] raw = new byte[256];    IntStream.range(0, 256).forEach(i -> raw[i] = (byte)i);    char[] table = new char[256];    cs.newDeprer().onUnmappableCharacter(CodingErrorAction.REPLACE)      .depre(ByteBuffer.wrap(raw), CharBuffer.wrap(table), true);    for(int i = 0; i < 128; i++)        if(table[i] != i) throw new UnsupportedOperationException("Not ASCII based");    return table;}

private static CharSequence mapAsciibasedText(Path p, char[] table) throws IOException {    try(FileChannel fch = FileChannel.open(p, StandardOpenOption.READ)) {        long actualSize = fch.size();        int size = (int)actualSize;        if(size != actualSize) throw new UnsupportedOperationException("file too large");        MappedByteBuffer mbb = fch.map(FileChannel.MapMode.READ_ONLY, 0, actualSize);        final class MappedCharSequence implements CharSequence { final int start, size; MappedCharSequence(int start, int size) {     this.start = start;     this.size = size; } public int length() {     return size; } public char charAt(int index) {     if(index < 0 || index >= size) throw new IndexOutOfBoundsException();     byte b = mbb.get(start + index);     return b<0? table[b+256]: (char)b; } public CharSequence subSequence(int start, int end) {     int newSize = end - start;     if(start<0 || end < start || end-start > size)         throw new IndexOutOfBoundsException();     return new MappedCharSequence(start + this.start, newSize); } public String toString() {     return new StringBuilder(size).append(this).toString(); }        }        return new MappedCharSequence(0, size);    }}

这允许将文件映射到虚拟内存并将其直接投影到

CharSequence
,而无需复制操作,前提是可以使用一个简单的表进行映射,并且对于基于ASCII的字符集,大多数字符甚至都不需要一个表查找,因为它们的数值与Unipre代码点相同。

使用这些方法,您可以将操作实现为

// You need this only once per JVM.// Note that running inside IDEs like Netbeans may change the default encodingchar[] table = getTable(Charset.defaultCharset());try(Stream<Path> stream = Files.walk(Paths.get(FILES_DIRECTORY))         .filter(Files::isRegularFile)) {    Pattern pattern = Pattern.compile(String.join("|", Strings_PASSWORDS));    long startTime = System.nanoTime();    final List<Path> filesWithObviousStringss = stream//.parallel() .filter(path -> {     try {         return pattern.matcher(mapAsciibasedText(path, table)).find();     } catch(IOException ex) {         throw new UncheckedIOException(ex);     } }) .collect(Collectors.toList());    System.out.println("Time taken = "        + TimeUnit.NANOSECONDS.toSeconds(System.nanoTime()-startTime) + " seconds");}

它的运行速度比普通文本转换快得多,但仍支持并行执行。

除了需要基于ASCII的单字节编码外,还有一个限制是该代码不支持大于2
GiB的文件。尽管可以扩展解决方案以支持更大的文件,但除非确实需要,否则我不会添加这种复杂性。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/515661.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号