2013-06-18 101 views
0

我正在製作一個程序,我將從文本文件中讀取數據並將它們存儲在mysql表中。 在我的程序中,用戶會給出文件所在的目錄,然後程序將只能找到.txt文件並繼續。之後將創建一個表格,它將有2個字段,並在這些字段中插入文本文件中的值。如何從文本文件中的特定行獲取表的值?

我的問題是,我不知道如何!我會解釋你的意思!在我的程序中,我將創建帶有字段(ID,名稱)的表格。這些字段的值必須來自文本文件。所有的文件如下:enter image description here

正如你所看到的ID是在文件的第三行,名稱是在第五。任何人都可以幫助我如何導入表中的ID和名稱值?我怎樣才能從文件中每次只獲得這些值?

做的第一個步驟的代碼是:

公共靜態無效主要(字符串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(); 
} 

}

私有靜態字符串getCreateTable1(連接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; 

}

+0

是否有一個簡單的字符分隔字段文本文件?例如。逗號或製表符? –

+0

是的,有標籤。 – dedmar

+1

我在下面發佈的代碼應該從.txt文件中提取名稱和ID字段 –

回答

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。我沒有插入這個,因爲我不記得它從我的頭頂,但你的IDE應該提示你插入,如果你使用的東西像Netbeans或Eclipse

+0

這個代碼在很多地方都是錯誤的。首先,你需要將'id'解析爲'int'。其次你需要關閉'BufferedReader'後,如果你正在使用Java 7,請使用try-with-resources。 –

+0

@BoristheSpider良好的調用,修復這些問題。在這臺機器上沒有設置java開發環境,很容易丟失東西 –

+0

它在Map nameByID = new HashMap <>()中也有錯誤。它不接受<>。我必須做什麼? – dedmar

0

你應該儘量不要重新發明輪子。

使用FileNameExtensionFilter來過濾.txt文件,這個類是從swing開始的,但在純java中使用它很好。

檢查每行是否匹配正則表達式模式,這樣您可以在驗證它的同時消化該行。

創建Person對象保存此信息並返回PersonCollection - 您封裝文件閱讀行爲從您的數據庫訪問層走的方式。

把這一切都在一個叫,說classFileReader和你有類似以下內容:

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,這是讀取文件的結果。 ListreadFile(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,這是使用Java 7交換機與String s。我們根據密鑰的值填充person,在需要的地方解析int

最後我們return人口稠密的人。

class應該讓你很好地實現你的目標 - 將Person對象sql插入數據庫是微不足道的。

您可能希望在文件讀取過程中添加更多驗證,例如檢查是否找到NAMEID。我把這留作練習。

相關問題