如何从文本文件中的特定行获取表的值?

时间:2013-06-18 11:50:33

标签: java jdbc

我创建一个程序,我将从文本文件中读取数据并将它们存储在mysql中的表中。 在我的程序中,用户将给出文件所在的目录,然后程序将只找到.txt文件并将继续。之后会创建一个表,它将有2个字段,在这些字段中,我会插入文本文件中的值。

我的问题是我不知道怎么做!我会解释你的意思!在我的程序中,我将使用字段(ID,Name)创建表。必须从文本文件中获取这些字段的值。所有文件如下所示:enter image description here

如您所见,ID位于文件的第三行,而Name位于第五行。任何人都可以帮助我如何在表中导入ID和Name的值?我怎样才能每次只从文件中获取这些值?

执行第一步的代码是:

public static void main(String args [])抛出异常{

Class.forName("com.mysql.jdbc.Driver");
Connection con = (Connection) DriverManager.getConnection(
        "jdbc:mysql://localhost:3306/mydb", "", "");

String dirpath = "";
Scanner scanner1 = new Scanner(System.in);
while (true) {
    System.out.println("Please give the directory:");
    dirpath = scanner1.nextLine();
    File fl = new File(dirpath);
    if (fl.canRead())

        break;
    System.out.println("Error:Directory does not exists");
}

try {
    String files;
    File folder = new File(dirpath);
    File[] listOfFiles = folder.listFiles();

    for (int i = 0; i < listOfFiles.length; i++) {
        if (listOfFiles[i].isFile()) {
            files = listOfFiles[i].getName();
            if (files.endsWith(".txt") || files.endsWith(".TXT")) {
                List<File> txtFiles = new ArrayList<File>();
                txtFiles.add(listOfFiles[i]);
                String[] parts = files.split("\\.");
                String tablename = parts[0];

                for (File txtFile : txtFiles) {
                    List sheetData = new ArrayList();

                    try {
                        FileReader in = new FileReader(txtFile);
                        BufferedReader br = new BufferedReader(in);
                        String line = br.readLine();
                        while (line != null) {
                            System.out.println(line);
                            line = br.readLine();

                        }
                        in.close();

                    } catch (Exception e) {
                        System.err.println("Error: " + e.getMessage());
                    }

                    getCreateTable1(con, tablename);
                    importData(con, txtFile, tablename);
                }
            }
        }
    }

} catch (Exception e) {
    System.out.println();
}

}

private static String getCreateTable1(Connection con,String tablename){

try {
    Class.forName("com.mysql.jdbc.Driver");
    Statement stmt = con.createStatement();
    String createtable = "CREATE TABLE "
            + tablename
            + " ( ID INT , name VARCHAR(255)";
    System.out.println("Create a new table in the database");
    stmt.executeUpdate(createtable);
} catch (Exception e) {
    System.out.println(((SQLException) e).getSQLState());
    System.out.println(e.getMessage());
    e.printStackTrace();
}

return null;

}

2 个答案:

答案 0 :(得分:0)

你应该尽量不重新发明轮子。

使用FileNameExtensionFilter过滤.txt个文件,此类来自swing,但在普通java中使用可以。

检查每一行是否与正则表达式模式匹配,这样您就可以在验证行的同时消化该行。

创建一个Person对象,其中包含此信息并返回Collection Person - 这样就可以将文件读取行为封装在远离数据库访问层的位置。

将所有这些内容放入class调用,例如FileReader,您就会有以下内容:

public class FileReader {

    private final Pattern linePattern = Pattern.compile("^(\\w++)\\s++(\\w++)\\s*+$");
    private final Pattern lineBreakPattern = Pattern.compile("\r?\n");
    private final FileFilter txtFilter = new FileNameExtensionFilter("*.txt", "txt");
    private final File txtFolder;

    public FileReader(File txtFolder) {
        this.txtFolder = txtFolder;
    }

    public List<Person> readFiles() {
        final List<Person> people = new LinkedList<>();
        for (final File txtFile : txtFolder.listFiles()) {
            if (txtFilter.accept(txtFile)) {
                people.add(readFile(txtFile));
            }
        }
        return people;
    }

    private Person readFile(File txtFile) {
        try (final Scanner scanner = new Scanner(txtFile)) {
            scanner.useDelimiter(lineBreakPattern);
            final Person person = new Person();
            while (scanner.hasNext()) {
                final String line = scanner.next();
                final Matcher matcher = linePattern.matcher(line);
                if (matcher.matches()) {
                    switch (matcher.group(1).toUpperCase()) {
                        case "ID":
                            person.setId(Integer.parseInt(matcher.group(2)));
                            break;
                        case "NAME":
                            person.setName(matcher.group(2));
                            break;
                        default:
                            throw new IOException("Illegal line '" + matcher.group() + "'.");
                    }
                }
            }
            return person;
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }

    public static final class Person {

        private int id;
        private String name;

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}

因此,您将使用包含文件的文件夹创建FileReader,然后调用readFiles,然后将返回的List<Person>保存在数据库中。

让我们通过这个课程。

readFiles方法循环遍历目录中的所有文件,并检查它们中的每一个是否与txtFilter匹配 - 这会筛选出任何非.txt文件。

readFiles方法还会创建并返回List<Person,这是读取文件的结果。 List方法填充了readFile(File txtFile)。该方法负责读取单个文件并将其解析为Person

Person类是一个非常简单的数据传输对象,包含属性和访问器。没有逻辑。

readFile方法在Java 7 try-with-resources构造中创建Scanner。它将分隔符设置为与平台无关的换行符模式(\r?\n表示它与\r\n\n匹配)然后循环扫描器输出。

使用linePattern处理每一行,这可能需要一些解释:

^(\\w++)\\s++(\\w++)\\s*+$
  • ^是“开始锚点”,即该行从此处开始
  • (\\w++)表示捕获任意数量的字符
  • \\s++表示跳过任意数量的空白字符
  • (\\w++)与上述相同
  • \\s*+表示跳过零个或多个空格字符
  • $是“结束锚”,即行的结尾

因此,如果模式匹配,我们有一个有效的行。此外,在验证我们抓住了字符的“组”时,这些是我们的关键和价值。

接下来,我们在第一组上使用switch,这是使用带有String的Java 7交换机。我们根据密钥的值填充person,并根据需要解析int

最后我们return填充的人。

这个class可以帮助您完成目标 - 将Person对象sql插入数据库是微不足道的。

您可能希望在文件阅读过程中添加更多验证,例如检查是否找到了NAMEID。我将此作为练习。

答案 1 :(得分:0)

BufferedReader br = new BufferedReader(new FileReader(new File("path/to/file")));

String currentLine = br.readLine();

Map<Integer, String> nameByID = new HashMap<Integer, String>(); 
while (currentLine != null) {

  String[] tokens = currentLine.split("\t");
  int id = Integer.parseInt(tokens[2]);
  String name = tokens[4];
  nameByID.put(id, name);
  currentLine = br.readLine();

}

br.close();

nameByID将包含您需要的姓名和ID。

请注意,调用创建新BufferedReader,调用readLine()和关闭BufferedReader时需要进行一些异常处理。我没有插入这个,因为我无法记住它,但如果你使用Netbeans或Eclipse之类的东西,你的IDE会提示你插入