递归不像我们期望的那样工作

时间:2014-06-08 21:06:01

标签: java recursion

对于一个项目,我们的数据库中有一个包含文件和文件夹的表。

就像这样

CREATE TABLE files (
    file_id INT PRIMARY_KEY AUTO_INCREMENT,
    file_type varchar(255) NOT NULL, // can be any mimetype or "dir" if it's a directory
    file_parent_id INT NOT NULL // contains the id of the directory the file is in
);

我们希望能够删除文件夹,当我们这样做时,删除该文件夹中的所有内容。 递归函数似乎是合适的但我们很难围绕递归的概念以及如何实现我们想要的东西。 Atm我们认为我们有一个很好的算法,但它只删除了每个文件夹的第一个文件夹(及其内容)。

public void deleteRecursively(Client client, int dir_id) {
        ResultSet res = FileModel.getSubdirs(client, dir_id);
        ResultSet files = FileModel.findFilesInDir(client, dir_id);
        if (res == null) {
            try {
                FileModel tmp = null;
                if (files != null) {
                    // deleting files in cur_dir
                    while (files.next()) {
                        tmp = FileModel.find(client, files.getInt("f_id"));
                        if (tmp != null) {
                            tmp.deleteMe(client);
                        }
                        tmp = null;
                    }
                }
                // deleting current_dir
                tmp = FileModel.find(client, dir_id);
                if (tmp != null) {
                    tmp.deleteMe(client);
                }
            } catch (Exception e) {
                e.printStackTrace();
                Logs.error(
                        e,
                        Thread.currentThread().getStackTrace()[2]
                                .getLineNumber() + " : " + e.getMessage());
            }
        } else {
            try {
                while (res.next()) {
                    this.deleteRecursively(client, res.getInt("f_id"));
                }
            } catch (Exception e) {
                e.printStackTrace();
                Logs.error(
                        e,
                        Thread.currentThread().getStackTrace()[2]
                                .getLineNumber() + " : " + e.getMessage());
            }
        }
    }

编辑:FileModel

package com.dev.model;

import java.io.File;
import java.sql.ResultSet;

import com.dev.logs.Logs;
import com.dev.main.Client;
import com.mysql.jdbc.PreparedStatement;

public class FileModel {
    private int f_id = -1;
    private int f_owner_id;
    private int f_parent_id;
    private String f_path;
    private String f_name;
    private double f_size;
    private String f_type;

    public FileModel(int f_owner_id, int f_parent_id, String f_path,
            String f_name, int f_size, String f_type) {
        this.f_owner_id = f_owner_id;
        this.f_parent_id = f_parent_id;
        this.f_path = f_path;
        this.f_name = f_name;
        this.f_size = f_size;
        this.f_type = f_type;
    }

    public FileModel(ResultSet res) {
        try {
            this.f_id = res.getInt("f_id");
            this.f_owner_id = res.getInt("f_owner_id");
            this.f_path = res.getString("f_path");
            this.f_size = res.getDouble("f_size");
            this.f_type = res.getString("f_type");
            this.f_name = res.getString("f_name");
            this.f_parent_id = res.getInt("f_parent_id");
        } catch (Exception e) {
            Logs.error(e, "Not provided", "Error Initializing file");
        }
    }

    public static ResultSet getSubdirs(Client client, int dir_id) {
        client.getDb().connect();
        PreparedStatement stmt = null;
        ResultSet res = null;
        try {
            stmt = (PreparedStatement) client
                    .getDb()
                    .getCon()
                    .prepareStatement(
                            "SELECT * from files WHERE f_parent_id = ? AND f_type = ?");
            stmt.setString(1, Integer.toString(dir_id));
            stmt.setString(2, "dir");
            res = stmt.executeQuery();
            if (!res.isBeforeFirst()) {
                return null;
            }
            return res;
        } catch (Exception e) {
            Logs.error(e,
                    Thread.currentThread().getStackTrace()[2].getLineNumber()
                            + " : " + e.getMessage());
        }
        return null;
    }

    public static FileModel find(Client client, int id) {
        client.getDb().connect();
        PreparedStatement stmt = null;
        FileModel ret = null;
        ResultSet res = null;
        try {
            stmt = (PreparedStatement) client
                    .getDb()
                    .getCon()
                    .prepareStatement(
                            "SELECT * from files WHERE f_id = ? AND f_owner_id = ?");
            stmt.setString(1, Integer.toString(id));
            stmt.setString(2, Integer.toString(client.getId()));
            res = stmt.executeQuery();
            if (!res.next()) {
                System.out.println("No records found");
                client.sendError("No file found for that id");
                return null;
            } else {
                ret = new FileModel(res);
            }
        } catch (Exception e) {
            Logs.error(e,
                    Thread.currentThread().getStackTrace()[2].getLineNumber()
                            + " : " + e.getMessage());
            return null;
        }
        return ret;
    }

    public static ResultSet findFilesInDir(Client client, int dir_id) {
        client.getDb().connect();
        PreparedStatement stmt = null;
        ResultSet res = null;
        try {
            stmt = (PreparedStatement) client
                    .getDb()
                    .getCon()
                    .prepareStatement(
                            "SELECT * from files WHERE f_parent_id = ?");
            stmt.setString(1, Integer.toString(dir_id));
            res = stmt.executeQuery();
            if (res.isBeforeFirst()) {
                return res;
            }
            return null;
        } catch (Exception e) {
            Logs.error(e, e.getMessage());
        }
        return null;
    }

    public int saveToDb(Client client) {
        client.getDb().connect();
        PreparedStatement stmt = null;

        try {
            if (this.f_id == -1) {
                stmt = (PreparedStatement) client
                        .getDb()
                        .getCon()
                        .prepareStatement(
                                "INSERT into files (f_owner_id,f_parent_id,f_path,f_name,f_size,f_type,f_created,f_modified) VALUES (?,?,?,?,?,?,NOW(),NOW())");
                stmt.setString(1, Integer.toString(this.f_owner_id));
                stmt.setString(2, Integer.toString(this.f_parent_id));
                stmt.setString(3, this.f_path);
                stmt.setString(4, this.f_name);
                stmt.setString(5, Double.toString(this.f_size));
                stmt.setString(6, this.f_type);
                return stmt.executeUpdate();
            } else {

                stmt = (PreparedStatement) client
                        .getDb()
                        .getCon()
                        .prepareStatement(
                                "UPDATE files SET f_parent_id = ?, f_name = ?, f_size= ?, f_type = ?, f_modified = NOW() WHERE f_id = ? AND f_owner_id = ?");
                stmt.setString(1, Integer.toString(this.f_parent_id));
                stmt.setString(2, this.f_name);
                stmt.setString(3, Double.toString(this.f_size));
                stmt.setString(4, this.f_type);
                stmt.setString(5, Integer.toString(this.f_id));
                stmt.setString(6, Integer.toString(this.f_owner_id));
                return stmt.executeUpdate();
            }
        } catch (Exception e) {
            Logs.error(e, "Not provided", e.getMessage());
        }
        return -1;
    }

    public void deleteMe(Client client) {
        try {
            if (this.f_id > 0) {
                client.getDb().connect();
                if (this.f_type.equals("dir") == false) {
                    File file = new File(this.f_path + this.f_name);
                    if (file.exists()) {
                        file.delete();
                    }
                }
                client.getDb().delete(
                        "DELETE FROM files WHERE f_id = '"
                                + Integer.toString(this.f_id) + "'");
                client.getDb().delete(
                        "DELETE FROM file_shared WHERE fs_file_id = '"
                                + Integer.toString(this.f_id) + "'");
                client.getDb().delete(
                        "DELETE FROM public_links WHERE pl_file_id = '"
                                + Integer.toString(this.f_id) + "'");
                client.getDb().disconnect();
            }
        } catch (Exception e) {
            Logs.error(e, e.getMessage());
        }
    }

    public int getF_parent_id() {
        return f_parent_id;
    }

    public void setF_parent_id(int f_parent_id) {
        this.f_parent_id = f_parent_id;
    }

    public int getF_id() {
        return f_id;
    }

    public void setF_id(int f_id) {
        this.f_id = f_id;
    }

    public int getF_owner_id() {
        return f_owner_id;
    }

    public void setF_owner_id(int f_owner_id) {
        this.f_owner_id = f_owner_id;
    }

    public String getF_path() {
        return f_path;
    }

    public void setF_path(String f_path) {
        this.f_path = f_path;
    }

    public double getF_size() {
        return f_size;
    }

    public void setF_size(double f_size) {
        this.f_size = f_size;
    }

    public String getF_type() {
        return f_type;
    }

    public void setF_type(String f_type) {
        this.f_type = f_type;
    }

    public String getF_name() {
        return f_name;
    }

    public void setF_name(String f_name) {
        this.f_name = f_name;
    }

}

我们哪里出错?

1 个答案:

答案 0 :(得分:1)

这是因为你正在以错误的顺序删除。

我认为它应该是这样的:

public void deleteRecursively(Client client, int dir_id) {
        ResultSet res = FileModel.getSubdirs(client, dir_id);

        /if we have some sub folders, we must do recursive call for these folders
        if (res != null) {
            try {
                while (res.next()) {
                    this.deleteRecursively(client, res.getInt("f_id"));
                }
            } catch (Exception e) {
                //....
            }
        }


        ResultSet files = FileModel.findFilesInDir(client, dir_id);

        if (files != null) {
            // deleting files in cur_dir
            while (files.next()) {
               tmp = FileModel.find(client, files.getInt("f_id"));
               if (tmp != null) {
                  tmp.deleteMe(client);
               }
               tmp = null;
            }
         }

        // deleting current_dir
        tmp = FileModel.find(client, dir_id);
        if (tmp != null) {
            tmp.deleteMe(client);
        }

    }