我有自己的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个中继并添加到列表中,如果该对象满足所有标准。我怎么能这样做?(没有该死的布尔标志)
答案 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)
行。