2014-04-17 2 views
0

표 ('\ 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을 사용하여 마침내 해결했다.

도움을 주셔서 감사합니다.

답변

0

삽입을 위해 여러 트랜잭션을 사용할 수 있습니다. 거래 당 200 개의 인서트를 가지고 놀고 거기에서 일할 수 있습니다. 삽입물의 양을 가지고 놀면 성능에 큰 영향을 미칩니다.

+0

내 첫 번째 아이디어 였기 때문에했으나 여전히 같은 오류가 있습니다. 제가 정확히 한 일을 보여주기 위해 주제를 편집 할 것입니다. 아마도 잘못하고있는 것일 수 있습니다. –

+0

해당 코드는 트랜잭션 당 200 개의 삽입을 실행하지 않습니다. while 루프 내에서 트랜잭션을 시작하고 커밋해야합니다. – meredrica

+0

매우 잘 이해하지 못해 죄송합니다. 내가하는 일 : - 거래 시작 중. - 내 두 번째 루프에 200 개의 인서트를 넣으십시오 (내 cpt가 사용됨). -이 200 개의 삽입 후에 트랜잭션을 종료합니다. 파일 끝에 없으면 다시 시작합니다. 처음으로 거래와 진술을 잘 이해하지 못합니다. "성명서.execute() "그냥 내 삽입을 선언하고, 트랜잭션을 끝내거나 잘못 입력 한 경우 삽입됩니까? –

관련 문제