如何考虑方法中的几个参数

时间:2017-06-05 20:47:11

标签: java file io

我有自己的SimpleFileVisitor实现和visitFile方法。 我想知道如果只有一个参数,我怎么能进行更精确的搜索。这就是我的意思

psql --version
psql (PostgreSQL) 9.4.0

主要方法:

public class SearchFileVisitor extends SimpleFileVisitor<Path>
{
    private String partOfName;
    private String partOfContent;
    private int minSize;
    private int maxSize;
    private List<Path> foundFiles = new ArrayList<>();

    public void setPartOfName(String partOfName)
    {
        this.partOfName = partOfName;
    }

    public void setPartOfContent(String partOfContent)
    {
        this.partOfContent = partOfContent;
    }

    public void setMinSize(int minSize)
    {
        this.minSize = minSize;
    }

    public void setMaxSize(int maxSize)
    {
        this.maxSize = maxSize;
    }

    public List<Path> getFoundFiles()
    {
        return foundFiles;
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException
    {
        if(partOfName != null && file.toString().contains(partOfName))
        {
           foundFiles.add(file);
        }
        else if(partOfContent != null)
            {
                try(Scanner scanner = new Scanner(file))
                {
                    while(scanner.hasNextLine())
                    {
                        String line = scanner.nextLine();
                        if(line.contains(partOfContent))
                        {
                            foundFiles.add(file);
                            break;
                        }
                    }
                }
            }
         else if(file.toFile().length() < maxSize)
         {
             foundFiles.add(file);
         }
         else if(file.toFile().length() > minSize)
         {
             foundFiles.add(file);
         }
        return super.visitFile(file, attrs);
    }
}

所以,如果我只设置partOfName,它应该只在它上传。但是,如果在它旁边我也设置了partOfContent并说maxSize,它同时应该在3个参数上进行中继。因此,如果有4个标准,它应该在4个中继并添加到列表中,如果该对象满足所有标准。我怎么能这样做?(没有该死的布尔标志)

3 个答案:

答案 0 :(得分:1)

您应该将逻辑结构为&#34;参数被禁用或文件传递参数检查&#34;对于每个参数。

首先,使用默认值表示参数已禁用:

private String partOfName = null;
private String partOfContent = null;
private int minSize = -1;
private int maxSize = -1;

然后你可以使用单个if语句,partOfContent检查一个单独的方法来保持简单:

@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
    if ((partOfName == null || file.toString().contains(partOfName))
            && (partOfContent == null || fileContains(file, partOfContent))
            && (maxSize < 0 || file.toFile().length() < maxSize)
            && (minSize < 0 || file.toFile().length() > minSize)) {
        foundFiles.add(file);
    }
    return super.visitFile(file, attrs);
}

private static boolean fileContains(Path file, String partOfContent) throws IOException {
    try (Scanner scanner = new Scanner(file)) {
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            if (line.contains(partOfContent)) {
                return true;
            }
        }
    }
    return false;
}

答案 1 :(得分:0)

请注意,这只是描述了一般的想法。在评论中,我可能会重新考虑类和方法名称。

我将介绍一个“谓词”并使用装饰器以声明方式描述预期结果。

Predicate的界面如下所示:

public interface Predicate {
    boolean matches (Path file, BasicFileAttributes attrs);
}

每个实例仅匹配一个标准,如名称和委托给另一个谓词进行其他测试:

public final class Named implements Predicate{

   private final Predicate mDelegate;
   private final String mPartOfName;

   public Named(String partOfName, Predicate delegate)
   {
       mPartOfName = partOfName;
       mDelegate = delegate;
   }

   @Override
   public boolean matches(Path file, BasicFileAttributes attrs)
   {
       return file.toString().contains(mPartOfName) && mDelegate.matches(file, attrs);
   }
}

或最大尺寸:

public final class MaxSized implements Predicate{

   private final Predicate mDelegate;
   private final int mMaxSize;

   public MaxSized(int maxSize, Predicate delegate)
   {
       mMaxSize = maxSize;
       mDelegate = delegate;
   }

   @Override
   public boolean matches(Path file, BasicFileAttributes attrs)
   {
       return file.toFile().length() < mMaxSize && mDelegate(file, attrs);
   }
}

“全部匹配”谓词看起来很简单:

public final class All implements Predicate{
   @Override
   public boolean matches(Path file, BasicFileAttributes attrs)
   {
       return true;
   }
}

SeachFileVisitor会缩小到这个:

public final class SearchFileVisitor extends SimpleFileVisitor<Path>{
    private final List<Path> foundFiles = new ArrayList<>();
    private final Predicate mPredicate;

    public SearchFileVisitor(Predicate predicate){
        mPredicate = predicate;
    }


    public List<Path> getFoundFiles() {
        return foundFiles;
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        if (mPredicate.matches(file, attrs)) {
            foundFiles.add(file);
        }
    }
}

你可以这样设置:

SearchFileVisitor searchFileVisitor =
    new SearchFileVisitor(
        new MaxSized(10000,
            new Named("John",
                new All())));

谓词可以被理解为“返回All元素Named,如"John",最大大小为10000”。您还可以像这样读取它:“匹配所有谓词的大小受限且名称受限的版本”。

  • 谓词是不可变的,因此在并发环境中没有副作用。
  • 所有课程都简短,易于测试。
  • 可以在不修改现有代码的情况下添加新谓词。
  • 没有“该死的布尔标志”

答案 2 :(得分:0)

你应该使用Stream&lt; Path&gt;而不是FileVisitor&lt; Path&gt;像这样。

static boolean contains(Path path, String partOfContent) {
    try (Scanner scanner = new Scanner(path)) {
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            if (line.contains(partOfContent)) {
                return true;
            }
        }
    } catch (IOException e) {
        return false;
    }
    return false;
}

public static void main(String[] args) throws IOException {
    List<Path> results = Files.walk(Paths.get("D:/SecretFolder"))
        .filter(path -> Files.isRegularFile(path))
        .filter(path -> path.toString().contains("Jhon"))
        .filter(path -> contains(path, "be or not to be?"))
        .filter(path -> path.toFile().length() >= 500)
        .filter(path -> path.toFile().length() <= 10000)
        .collect(Collectors.toList());
    results.stream()
        .forEach(System.out::println);
}

如果您不想查看最小文件大小,请删除第.filter(path -> path.toFile().length() >= 500)行。