getBlob()返回意外字节和数据库列数据类型自动更改

时间:2014-01-23 08:48:09

标签: android database sqlite

我有一个预先填充的SQLite数据库,有两个表:

  

表1:AudioSamples(_id文本主键,AudioFile blob)

          where _id --> name of the audio file 
          AudioFile --> audio file (.PCM file) 
     

表2:android_metadata(语言环境文本)

          where locale --> 'en_US'

我所做的是:

  1. 我将此表放入android资源文件夹,然后我的应用程序首次启动应用程序时将其复制到系统数据库。
  2. 我使用getBlob()函数访问blob字段'AudioFile',该函数返回字节数组。
  3. 当我将字节数组的内容写入AudioTrack对象时,我可以听到我的音频文件,但噪音很大。
  4. 问题是:

    1. 当我将数据库从系统数据库文件夹拉到我的电脑并检查“AudioFile”列的数据类型时,它给我输入'text'而不是'blob'。
    2. getBlob()返回的字节数超出预期。
    3. 我的音频播放代码适用于其他pcm文件。

      插入.pcm文件的代码:

      private static void insertFile(char FileName){
              String filepath="C:/Documents and Settings/Administrator/Desktop/imp files/"+FileName+".pcm";
              try{
                  PreparedStatement pstmt=c.prepareStatement("insert into AudioSamples values(?,?)");
                  File f=new File(filepath);
                  FileInputStream fin=new FileInputStream(f);
                  byte[] buff=new byte[(int)f.length()];
                  fin.read(buff);
      
                  pstmt.setString(1,String.valueOf(FileName));
                  pstmt.setBytes(2,buff);
                  pstmt.executeUpdate();
                  pstmt.clearParameters();
                  fin.close();
                  System.out.println("Inserted file :"+FileName+".pcm size="+(buff.length/1024)+"KB");
              }catch(Exception e){
                  System.err.print("Error :"+e);
              }
          }
      

      我在使用代码将数据放入资产之前检查了我的表数据:

      private static void GetTableData(String TableName){
      
              try{
                  Statement stmt=c.createStatement();
                  String myquery="select * from "+TableName;
                  ResultSet rs=stmt.executeQuery(myquery);
      
                  while(rs.next()){
                      System.out.println("For "+rs.getString("_id")+".pcm :");
                      System.out.println("size="+rs.getBytes(rs.getMetaData().getColumnName(2)).length/1024+"KB");
                      System.out.println("column1 name:"+rs.getMetaData().getColumnName(1));
                      System.out.println("column1 type:"+rs.getMetaData().getColumnType(1));
                      System.out.println("column2 name:"+rs.getMetaData().getColumnName(2));
                      System.out.println("column2 type:"+rs.getMetaData().getColumnType(2));
                  }
      
                  rs.close();
                  stmt.close();
              }catch(Exception e){
                  System.err.println("GetTableData()"+e.getMessage());
              }
          }
      

      这给了我在日志中的预期结果:

        

      对于a.pcm:size = 27KB

           

      column1 name:_id

           

      column1类型:12

           

      column2 name:AudioFile

           

      column2类型:2004

      将资产中的数据库文件'AudioData.db'复制到系统数据库的代码:

      private void copyDatabase() throws IOException{
              //stream to read database in assets folder
              InputStream ipstream = myContext.getAssets().open("AudioData.db");
      
              //stream to write to empty database in system folder
              FileOutputStream opstream= new FileOutputStream(DB_PATH+DB_NAME);
      
              byte[] buff=new byte[1024*512];  //create 512Kb buffer
              int bytesRead=0;
              while((bytesRead=ipstream.read(buff))!=(-1)){
                  opstream.write(buff, 0, bytesRead); //write to empty db in systems folder
              }
              Log.v(DB_NAME,"Database copied");
      
              //close streams
              opstream.flush();
              opstream.close();
              ipstream.close();
              Log.v("myDataBase status",""+(myDataBase!=null));
          }
      

      这是我访问pcm文件的代码:

       public byte[] getPCMFile(String FileName){
                  Cursor cursor=null; 
                  byte[] buff = null;
      
                  try{
                      cursor=myDataBase.query("AudioSamples",null,"_id=?",new String[]{FileName},null, null,null);
                      Log.v("getPCMFile()","Obtained table has Column  count="+cursor.getColumnCount());  
                      cursor.moveToFirst();
                      Log.v(FileName+".pcm", "_id columntype="+cursor.getType(cursor.getColumnIndex("_id")));
                      Log.v(FileName+".pcm", "AudioFile columntype="+cursor.getType(cursor.getColumnIndex("AudioFile")));
                      buff=cursor.getBlob(cursor.getColumnIndex("AudioFile"));
                      Log.v("getPCMFile()","Blob retrived :"+cursor.getString(cursor.getColumnIndex("_id"))+".pcm size="+buff.length);
                  }catch(Exception e){
                      Log.e("getPCMFile()","Couldnt read PCM file "+FileName+".pcm", e);
                  }       
      
                  cursor.close();
                  return buff;    //return byte array containing pcm samples
              }
      

      对于getPCMFile('a'),它给我的日志为:

        

      获取的表具有列计数= 2

           

      AudioFile columntype = 3

           

      _id columntype = 3

           

      Blob重新获得:a.pcm size = 49046

      AudioFile columntype应为2004(对于blob),并且a.pcm的实际大小为27124,但它正在恢复49046个byes。 请帮我。提前谢谢!

1 个答案:

答案 0 :(得分:0)

我认为在Android中不首选将音频文件存储在数据库中。

并使用instst文件夹instaed来存储您的音频文件。

将您的音频文件保存在assest文件夹中,并将相关信息保存在数据库中。

希望有所帮助