#java #sqlite
#java #sqlite
Вопрос:
У меня возникли некоторые проблемы при управлении хранением данных с помощью запроса (NetBeans-> Java-> Sqlite):
- 1) У меня есть папка с некоторым текстовым файлом, содержащим несколько строк текста (файлы не превышают 2 Кб)
- 2) Программа последовательно открывает файлы и сохраняет каждое слово в таблице
- 3) Когда программа начинает анализировать слишком много данных (некоторое время более 40 файлов или более 82), возвращает следующую ошибку
Исключение в потоке «main» java.sql.SQLException: не удается открыть файл базы данных в org.sqlite.DB.throw x (DB.java: 288) в org.sqlite.DB.executeBatch (DB.java: 236) в org.sqlite.PrepStmt.executeBatch (PrepStmt.java: 83)
- Ошибка в int [] upCountsb = prepb.executeBatch();
Вот код:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public static void main(String[] args) throws ClassNotFoundException, SQLException, IOException, InterruptedException {
Class.forName("org.sqlite.JDBC");
Connection conn = DriverManager.getConnection("jdbc:sqlite:C:/Users/.../test.db");
Statement stmt;
stmt = conn.createStatement();
stmt.executeUpdate("DROP TABLE IF EXISTS words");
stmt.executeUpdate("CREATE TABLE words (words)");
String path_dir ="C:/Users/.../good";
File currentDIR = new File("C:/Users/.../good");
File files[]=currentDIR.listFiles();
String tmp="";
ArrayList app = new ArrayList();
//Search in DIR for Files
for( File f1 : files ){
String nameFile = f1.getName();
FileReader f = null;
BufferedReader fIN = null;
String s;
//Open the file xxx.txt
try{
f = new FileReader(path_dir "/" nameFile);
fIN = new BufferedReader(f);
s = fIN.readLine();
while(s != null) {
StringTokenizer st = new StringTokenizer(s);
while(st.hasMoreTokens()) {
String str = st.nextToken().toString().toLowerCase();
Pattern pattern =Pattern.compile("\W", Pattern.MULTILINE);
String newAll = pattern.matcher(str).replaceAll("").trim();
tmp=newAll;
app.add(tmp); //Add all data in the ArrayList app
} // Close While 'hasMoreTokens'
s = fIN.readLine();
} //Close While on File
} //Close TRAY
catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
f.close(); //Close FileReader
} //Close Scan DIR for FILE
//Add all data in the Tbl od Database
PreparedStatement prep = conn.prepareStatement("insert into words values (?);");
for (int z=0; z<app.size();z ){
prep.setString(1,app.get(z).toString().toLowerCase());
prep.addBatch();
conn.setAutoCommit(false);
prep.executeBatch(); ***//Here I get the error although i use int [] Count =prep.executeBatch();***
conn.setAutoCommit(true);
}
prep.close();
} //Close MAIN
Ответ №1:
Вам необходимо освободить используемые ресурсы, как только вы закончите с ними. Например prepb.close()
после выполнения инструкции.
То же самое касается ваших файловых дескрипторов.
Кроме того, теряется смысл пакетной обработки, если вы выполняете инструкцию для каждой вставки.
Поскольку ваши файлы очень маленькие, вы могли бы также подготовить все данные в памяти, прежде чем сохранять их в базе данных.
package stackoverflow.wordanalysis;
import java.io.*;
import java.sql.*;
import java.util.*;
import java.util.regex.*;
public class WordFrequencyImporter {
public static void main(String[] args) throws Exception {
List<String> words = readWords("the-directory-from-which-to-read-the-files");
Class.forName("org.sqlite.JDBC");
Connection conn = DriverManager.getConnection("jdbc:sqlite:test.db");
try {
createWordsTable(conn);
persistWords(words, conn);
} finally {
conn.close();
}
}
private static void persistWords(List<String> words, Connection conn)
throws SQLException {
System.out.println("Persisting " words.size() " words");
PreparedStatement prep = conn
.prepareStatement("insert into words values (?);");
try {
for (String word : words) {
prep.setString(1, word);
prep.addBatch();
}
conn.setAutoCommit(false);
prep.executeBatch();
conn.setAutoCommit(true);
} finally {
prep.close();
}
}
private static void createWordsTable(Connection conn) throws SQLException {
Statement stmt = conn.createStatement();
try {
stmt.executeUpdate("DROP TABLE IF EXISTS words");
stmt.executeUpdate("CREATE TABLE words (words)");
} finally {
stmt.close();
}
}
private static List<String> readWords(String path_dir) throws IOException {
Pattern pattern = Pattern.compile("\W", Pattern.MULTILINE);
List<String> words = new ArrayList<String>();
for (File file : new File(path_dir).listFiles()) {
BufferedReader reader = new BufferedReader(new FileReader(file));
System.out.println("Reading " file);
try {
String s;
while ((s = reader.readLine()) != null) {
StringTokenizer st = new StringTokenizer(s);
while (st.hasMoreTokens()) {
String token = st.nextToken().toString().toLowerCase();
String word = pattern.matcher(token).replaceAll("")
.trim();
words.add(word);
}
}
} finally {
reader.close();
}
}
return words;
}
}
Комментарии:
1. Спасибо за ответ! Я тестирую ваше решение… дайте мне минутку
2. Здравствуйте, я проанализировал и протестировал ваше решение, но по-прежнему получаю ту же ошибку. следовать измененному коду:
3. Пожалуйста, покажите нам весь код, включая ту часть, где вы инициализируете
conn
.4. Привет! Я изменил код в окне вопроса, теперь вы можете увидеть инициализацию conn.
5. Я добавил пример, который надлежащим образом обрабатывает ресурсы и не выполняет подготовленную инструкцию более одного раза. Он был протестирован примерно на 200 файлах, содержащих в общей сложности 887888 слов. Решает ли это вашу проблему?