표 ('\ t')로 구분 된 CSV 파일을 읽고 각 셀을 Android의 로컬 데이터베이스 (SQLite)에 삽입하려고합니다. CursorWindow/W (27577)를 : 나는 파일을 읽고, 내 데이터베이스에있는 각 행을 삽입하지만 오류 수 :대용량 CSV 파일에서 SQLite에 많은 행 삽입 - 창이 완전 오류입니다.
04-17 14 : 52 : 00.529를 요청 할당 204 바이트 : 윈도우가 가득 공간 198 바이트를, 창 크기 2097152 바이트
04-17 (14) 무료 : 52 : 00.545 : E/생산성 카운트 (27577) : 생산성 수 : 7009 개
모든 행이 삽입 된 것 같다 (내가 7009 행을 가지고)하지만 내 CSV 파일에 행의 특정 번호를 얻을 때마다 나는 창 전체 오류입니다. 이 오류는 데이터베이스에 BLOB가있을 때 발생하지만 그럴 필요가 없습니다.
응용 프로그램이 작동하는 것처럼 보이지만 이전에 수행했던 작업을 조금 더 이해하고 싶습니다. (성능을 향상시키기 위해 찾은 내용을 많이 사용했지만 잘 이해하지 못했습니다.)
코드 :
이 // Find the directory for the SD Card using the API
// *Don't* hardcode "/sdcard"
File sdcard = Environment.getExternalStorageDirectory();
// Get the text file
File file = new File(sdcard, "/my_application/update/testCSV7.txt");
// It's a CSV file
BufferedReader buffer = new BufferedReader(new InputStreamReader(
new FileInputStream(file), "Cp1252")); // Cp1252 = ANSI
String line = "";
line = buffer.readLine();
int cpt = 0;
int cpt2 = 0;
SQLiteDatabase db = this.getWritableDatabase();
Cursor myCursor = db.rawQuery("PRAGMA synchronous=OFF", null); // Is this usefull?
myCursor.close();
try {
db.setLockingEnabled(false); // Is it usefull?
String sql = "INSERT INTO " + TABLE_PROD
+ " VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);";
SQLiteStatement statement = db.compileStatement(sql);
db.beginTransaction();
while ((line = buffer.readLine()) != null) {
try {
String[] cells = line.split("\t", -1);
if (cells.length != 186) {
cpt2++;
Log.d("ERROR", "Strange size " + line);
} else {
statement.clearBindings();
int c = 1;
statement.bindString(c++, cells[20] + "");
statement.bindString(c++, cells[22] + "");
statement.bindString(c++, cells[23] + "");
statement.bindString(c++, cells[3] + "");
statement.bindString(c++, cells[6] + "");
statement.bindString(c++, cells[8] + "");
statement.bindString(c++, cells[10] + "");
statement.bindString(c++, cells[13]);
statement.bindString(c++, cells[31] + "");
statement.bindString(c++, cells[104] + "");
statement.bindString(c++, cells[105] + "");
statement.bindString(c++, cells[106] + "");
statement.bindString(c++, cells[112] + 0);
statement.bindString(c++, cells[114] + 0);
statement.bindString(c++, cells[140] + cells[141] + "");
statement.bindString(c++, cells[184] + "");
statement.bindString(c++, cells[185] + "");
statement.execute();
Log.d("COMPTEUR : ", cpt + " CPT 2 : " + cpt2);
}
} catch (Exception e) {
e.printStackTrace();
Log.d("Exception : ", cpt + " Error");
}
cpt++;
}
db.setTransactionSuccessful();
db.endTransaction();
} finally {
db.setLockingEnabled(true); // Is it usefull?
}
db.close();
buffer.close();
}
내 CSV 파일이 186 열과 (처음으로) 7010 행이 포함되어 있습니다. 나는 그들 중 소수만 원한다.
아무도 나에게 왜 내가이 메시지를 얻었는지, 내가 뭘 잘못하고 있는지, 그리고 어떤 것이 내 코드에서 쓸모 없는지를 설명해 주시면 감사하겠습니다.
내 로컬 데이터베이스 :
CREATE TABLE GERS_prod(prod_num TEXT PRIMARY KEY,
prod_design TEXT,prod_design_complete TEXT,prod_marque TEXT,prod_rayon TEXT,
prod_famille TEXT,prod_ss_famille TEXT,prod_code_vie TEXT,prod_quantite REAL,
prod_gencod_foire TEXT,prod_gencod_ref TEXT,prod_emballage TEXT,
prod_colisage REAL,prod_ss_colisage REAL,prod_desc TEXT,prod_couleur TEXT,
prod_matiere TEXT)
편집 : 나는 또한 문제였다 생각 (200)에 의해 거래를했다,하지만 같은 오류가 있습니다. 나는 CursorWindow를 얻는 이유를 이해하지 못한다.
File sdcard = Environment.getExternalStorageDirectory();
File file = new File(sdcard, "/my_application/update/testCSV7.txt");
BufferedReader buffer = new BufferedReader(new InputStreamReader(
new FileInputStream(file), "Cp1252")); // Cp1252 = ANSI
String line = "";
line = buffer.readLine();
int cpt = 0;
int cpt2 = 0;
SQLiteDatabase db = this.getWritableDatabase();
Cursor myCursor = db.rawQuery("PRAGMA synchronous=OFF", null);
myCursor.close();
String sql = "INSERT INTO " + TABLE_PROD
+ " VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);";
while (line != null) {
SQLiteStatement statement = db.compileStatement(sql);
db.beginTransaction();
cpt = 0;
while ((line = buffer.readLine()) != null && cpt < 200) {
try {
String[] cells = line.split("\t", -1);
if (cells.length != 186) {
cpt2++;
Log.d("ERROR", "Strange size : " + line.length() + " Line : " + line);
} else {
statement.clearBindings();
int c = 1;
statement.bindString(c++, cells[20] + ""); // Numprod
statement.bindString(c++, cells[22] + ""); // Désignation
statement.bindString(c++, cells[23] + ""); // Désignation
// complète
statement.bindString(c++, cells[3] + ""); // marque
statement.bindString(c++, cells[6] + ""); // rayon
statement.bindString(c++, cells[8] + ""); // famille
statement.bindString(c++, cells[10] + ""); // sous-famille
statement.bindString(c++, cells[13]); // Code vie
statement.bindString(c++, cells[31] + ""); // Quantité
statement.bindString(c++, cells[104] + ""); // gencod
// Foire
statement.bindString(c++, cells[105] + ""); // gencod
// ref
statement.bindString(c++, cells[106] + ""); // emballage
statement.bindString(c++, cells[112] + 0); // colisage
statement.bindString(c++, cells[114] + 0); // sous-colisage
statement.bindString(c++, cells[140] + cells[141] + ""); // Concat
// des
// descriptions
statement.bindString(c++, cells[184] + ""); // couleur
statement.bindString(c++, cells[185] + ""); // matière
statement.execute();
Log.d("COMPTEUR : ", cpt + " CPT 2 : " + cpt2);
}
} catch (Exception e) {
e.printStackTrace();
Log.d("COMPTEUR : ", cpt + " CPT 2 : " + cpt2);
}
cpt++;
}
db.setTransactionSuccessful();
db.endTransaction();
}
db.close();
buffer.close();
편집 2 : 내가 뭔가 잘못하고 있어요 경우
코드, 내 문제는 내 MainActivity에 전화를 내 getProdCount() 함수에 있었다. 나는 LIMIT와 OFFSET을 사용하여 마침내 해결했다.
도움을 주셔서 감사합니다.
내 첫 번째 아이디어 였기 때문에했으나 여전히 같은 오류가 있습니다. 제가 정확히 한 일을 보여주기 위해 주제를 편집 할 것입니다. 아마도 잘못하고있는 것일 수 있습니다. –
해당 코드는 트랜잭션 당 200 개의 삽입을 실행하지 않습니다. while 루프 내에서 트랜잭션을 시작하고 커밋해야합니다. – meredrica
매우 잘 이해하지 못해 죄송합니다. 내가하는 일 : - 거래 시작 중. - 내 두 번째 루프에 200 개의 인서트를 넣으십시오 (내 cpt가 사용됨). -이 200 개의 삽입 후에 트랜잭션을 종료합니다. 파일 끝에 없으면 다시 시작합니다. 처음으로 거래와 진술을 잘 이해하지 못합니다. "성명서.execute() "그냥 내 삽입을 선언하고, 트랜잭션을 끝내거나 잘못 입력 한 경우 삽입됩니까? –