1.引入#include "dirent.h"
2.相关结构体
(1)DIR
struct DIR {
struct dirent ent;
struct _WDIR *wdirp;
};
typedef struct DIR DIR;
(2)dirent
struct dirent {
long d_ino; /* Always zero */
unsigned short d_reclen; /* Structure size */
size_t d_namlen; /* Length of name without \0 */
int d_type; /* File type */
char d_name[PATH_MAX]; /* File name */
};
typedef struct dirent dirent;
2.c++遍历文件
void showAllFiles(string dir_name) {
if (dir_name.empty()) {
LOGE("dir_name is null !");
return;
}
DIR *dir = opendir(dir_name.c_str());
if (NULL == dir) {
LOGE("Can not open dir,Check path or permission!");
return;
}
dirent *file;
while ((file = readdir(dir)) != NULL) { //类似BufferedReader.readLine(),不过这里返回是dirnet*,不是string
if (file->d_type == DT_DIR) { //是目录则递归
string filePath = dir_name + "/" + file->d_name;
showAllFiles(filePath);
} else { //是文件则输出文件名
LOGE("filePath:%s%s", dir_name.c_str(), file->d_name);
}
}
closedir(dir); //opendir(char* dir)后要closedir(DIR *dir )
}
3.通过比较发现,使用JNI遍历速度特别快,我这里个人测试手机的 根目录"/storage/emulated/0"
JNI不到0.5秒,而JAVA用了3.5秒左右,怪不得招聘时一个个都优先会JNI NDK开发的,性能提升是真的好。
JAVA筛选目录下的所以txt文件
fun showJavaAllFiels(path:String){
var file: File = File(path)
if(file.exists()){
for(fileitm in file.listFiles()){
if (fileitm.isFile){
if(fileitm.name.endsWith(".txt"))
Log.e("native",path+"/"+fileitm.name)
}else{
showJavaAllFiels(path+"/"+fileitm.name)
}
}
}else{
Log.e("native","file is not exit!")
}
}
JNI筛选目录下的所以txt文件
void showAllFiles(string dir_name) {
if (dir_name.empty()) {
LOGE("dir_name is null !");
return;
}
DIR *dir = opendir(dir_name.c_str());
if (NULL == dir) {
LOGE("Can not open dir,Check path or permission!");
return;
}
dirent *file;
while ((file = readdir(dir)) != NULL) {
if (strcmp(file->d_name, ".") == 0 || strcmp(file->d_name, "..") == 0) {
// LOGE("ignore . and ..");
continue;
}
if (file->d_type == DT_DIR) {
string filePath = dir_name + "/" + file->d_name;
showAllFiles(filePath);
} else {
string filename = file->d_name;
int size = filename.size();
if(filename.size()>3){
string endName = filename.substr(size-4,size-1);
int flag = strcmp(endName.c_str(),".txt");
if(flag==0){
LOGE("filePath:%s/%s", dir_name.c_str(), file->d_name);
}
}
}
}
closedir(dir);
}
4.读写txt文件
fun readTxtFile(path:String){
var file = File(path)
if(file.exists()){
try {
//读
//InputStream 是字节输入流的所有类的超类,一般我们使用它的子类,如FileInputStream等.
//OutputStream是字节输出流的所有类的超类,一般我们使用它的子类,如FileOutputStream等.
var fileInPutString = FileInputStream(file)
//InputStreamReader 是字节流通向字符流的桥梁,它将字节流转换为字符流.
//OutputStreamWriter是字符流通向字节流的桥梁,它将字符流转换为字节流.
var inputStreamReader = InputStreamReader(fileInPutString)
//BufferedReader从字符输入流中读取文本,缓冲各个字符
//BufferedWriter将文本写入字符输出流,缓冲各个字符
var bufferReader = BufferedReader(inputStreamReader)
var txt:String =""
var i= 0
while (bufferReader.readLine()?.also { txt = it }!=null){
i++;
Log.e("txt",i.toString()+txt)
}
bufferReader.close()
inputStreamReader.close()
fileInPutString.close()
//写
var newFile = File("/storage/emulated/0/1/new.txt");
var outPutStream = FileOutputStream(newFile)
var outPutStreamWrite = OutputStreamWriter(outPutStream)
var bufferWriter = BufferedWriter(outPutStreamWrite)
bufferWriter.write("我 在 write file txt")
bufferWriter.close()
outPutStreamWrite.close()
outPutStream.close()
}catch (e:IOException){
}
}
}
5.also扩展函数是和let相同,函数体内使用it代表调用对象object,不同点是返回值是当前对象,let返回的是最后一行或指定的return表达式。?.also{}表示object不为null才会执行函数体。