12-14 19:51:30.346 17770-18098/com.company.package E/SQLiteLog: (14) cannot open file at line 32440 of [bda77dda96]
12-14 19:51:30.346 17770-18098/com.company.package E/SQLiteLog: (14) os_unix.c:32440: (30) open(./etilqs_3P2SKRP0Ge6cj3T) -
12-14 19:51:30.346 17770-18098/com.company.package E/SQLiteLog: (14) statement aborts at 180: [SELECT M.*,…………………
可以看到是打开一个”./etilqs_3P2SKRP0Ge6cj3T”的文件时打开失败。
先查查这个临时文件是什么鬼,
在sqlite3.c搜索前缀etilqs_里可以看到这样的注释:
/*** Temporary files are named starting with this prefix followed by 16 random** alphanumeric characters, and no file extension. They are stored in the** OS's standard temporary file directory, and are deleted prior to exit.** If sqlite is being embedded in another program, you may wish to change the** prefix to reflect your program's name, so that if your program exits** prematurely, old temporary files can be easily identified. This can be done** using -DSQLITE_TEMP_FILE_PREFIX=myprefix_ on the compiler command line.**** 2006-10-31: The default prefix used to be "sqlite_". But then** Mcafee started using SQLite in their anti-virus product and it** started putting files with the "sqlite" name in the c:/temp folder.** This annoyed many windows users. Those users would then do a ** Google search for "sqlite", find the telephone numbers of the** developers and call to wake them up at night and complain.** For this reason, the default name prefix is changed to be "sqlite" ** spelled backwards. So the temp files are still identified, but** anybody smart enough to figure out the code is also likely smart** enough to know that calling the developer will not help get rid** of the file.*/#ifndefSQLITE_TEMP_FILE_PREFIX# defineSQLITE_TEMP_FILE_PREFIX"etilqs_"#endif
总之就是临时文件就对了。
临时文件源码追踪
然后找找这个东西在哪里用的,
/*** Create a temporary file name in zBuf. zBuf must be allocated** by the calling process and must be big enough to hold at least** pVfs->mxPathname bytes.*/staticintunixGetTempname(int nBuf,char*zBuf){staticconstunsignedchar zChars[]="abcdefghijklmnopqrstuvwxyz""ABCDEFGHIJKLMNOPQRSTUVWXYZ""0123456789";unsignedint i, j;constchar*zDir; /* It's odd to simulate an io-error here, but really this is just ** using the io-error infrastructure to test that SQLite handles this ** function failing. */SimulateIOError( return SQLITE_IOERR ); zDir =unixTempFileDir();if( zDir==0 ) zDir ="."; /* Check that the output buffer is large enough for the temporary file ** name. If it is not, return SQLITE_ERROR. */if( (strlen(zDir)+strlen(SQLITE_TEMP_FILE_PREFIX)+18) >= (size_t)nBuf ){return SQLITE_ERROR; }do{sqlite3_snprintf(nBuf-18, zBuf,"%s/"SQLITE_TEMP_FILE_PREFIX, zDir); j = (int)strlen(zBuf);sqlite3_randomness(15,&zBuf[j]);for(i=0; i<15; i++, j++){ zBuf[j] = (char)zChars[ ((unsignedchar)zBuf[j])%(sizeof(zChars)-1) ]; } zBuf[j] =0; zBuf[j+1] =0; }while( osAccess(zBuf,0)==0 );return SQLITE_OK;}
/*** Return the name of a directory in which to put temporary files.** If no suitable temporary file directory can be found, return NULL.*/staticconstchar*unixTempFileDir(void){staticconstchar*azDirs[]= {0,0,0,"/var/tmp","/usr/tmp","/tmp", /* List terminator */ };unsignedint i;struct stat buf;constchar*zDir =0; azDirs[0] = sqlite3_temp_directory;if( !azDirs[1] ) azDirs[1] =getenv("SQLITE_TMPDIR");if( !azDirs[2] ) azDirs[2] =getenv("TMPDIR");for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){if( zDir==0 ) continue;if( osStat(zDir,&buf) ) continue;if( !S_ISDIR(buf.st_mode) ) continue;if( osAccess(zDir,07) ) continue;break; }return zDir;}
azDirs[0]是sqlite3_temp_directory,我们没有设置过,
azDirs[1]和[2]是环境变量,用sqlite3_log打出来是
即环境变量里没有设置这两个值,
而另外三个目录/var/tmp,/usr/tmp,/tmp在Android系统里都是应用不可写的,
所以会返回0给unixGetTemp,
于是unixGetTemp使用了”.”作为临时文件的目录,
那”.”是哪个目录呢?
使用
system(“ls . >/sdcard/0.txt”);
结果是:
acct
adb_keys
cache
config
d
data
default.prop
dev
etc
firmware
fstab.qcom
init
init.goldfish.rc
init.qcom.class_core.sh
init.qcom.class_main.sh
init.qcom.rc
init.qcom.sh
init.qcom.usb.rc
init.qcom.usb.sh
init.rc
init.target.rc
init.trace.rc
init.usb.rc
mnt
persist
proc
root
sbin
sdcard
storage
storage_int
sys
system
tombstones
ueventd.goldfish.rc
ueventd.qcom.rc
ueventd.rc
vendor