使用Android (ndk)在C++中打开和读取文本文件

3

我正在尝试制作一个在Android中使用C++ OpenCV的应用程序。 我面临的问题是我想从本地部分打开一个文本文件,逐个单词地读取它,但它无法打开。我的代码如下:

JNI方法:

JNIEXPORT jboolean JNICALL Java_com_alejandro_nativeopencv_NativeClass_initRecognizer(JNIEnv * env, jclass clazz){

    recognizer = Recognizer("ORB","ORB","BruteForce-Hamming");
    recognizer.createObject("/storage/emulated/0/TFG/Fotos/Carpeta", true);
    recognizer.createObject("/storage/emulated/0/TFG/Fotos/Cereales", true);

    return true;
}

我正在使用的 Recognizer::createObject 方法:

Recognizer.cpp:

#include "headers/Recognizer.h"
#include <fstream>
#include <iostream>
#include <string>
#include <android/log.h>

using namespace std;
using namespace cv;

//...other methods, constructors and stuff...

Object Recognizer::createObject(String path, bool add) {
    __android_log_print(ANDROID_LOG_DEBUG,"path","%s",(path + "/info.txt").c_str());
    ifstream file((path + "/info.txt").c_str());
    if (!file.is_open()){
        //always enters here
        return Object(true);  //null object
    } else{
        //never enters here
        String name;
        vector < vector<KeyPoint> > keypoints;
        vector <Mat> descriptors;
        vector < vector<Point2f> > corners;
        vector <String> viewNames;
        bool easy;

        string word;
        int i = 0;
        while (file >> word)
        {
            if(i == 0){

                /* Object name */
                name = word;

                __android_log_print(ANDROID_LOG_DEBUG,"NOMBRE","%s",name.c_str());

            } else if(i == 1){

                /* Object easy or not */
                easy = (word == "true");
                __android_log_print(ANDROID_LOG_DEBUG, "EASY", "%d", easy);
            } else if(i%2 == 0){

                /* Object image view*/
                keypoints.push_back(vector <KeyPoint>());
                descriptors.push_back(Mat());
                corners.push_back(vector <Point2f>(4));

                Mat image = imread(path + "/" + word, CV_LOAD_IMAGE_GRAYSCALE);
                this->detector->detect(image, keypoints[(i/2)-1]);
                this->extractor->compute(image, keypoints[(i/2)-1], descriptors[(i/2)-1]);
                corners[(i/2)-1][0] = cvPoint(0,0);
                corners[(i/2)-1][1] = cvPoint(image.cols,0);
                corners[(i/2)-1][2] = cvPoint(image.cols, image.rows);
                corners[(i/2)-1][3] = cvPoint(0, image.rows);
                __android_log_print(ANDROID_LOG_DEBUG, "VISTA", "%d", (i/2)-1);
            } else{

                /* Object name view */
                viewNames.push_back(word);

                String aux = word;
                __android_log_print(ANDROID_LOG_DEBUG, "VISTA NOMBRE", "%s", aux.c_str());
            }

            i++;
        }
        Object obj = Object(name, keypoints, descriptors, corners, viewNames, easy);

        if(add){
            this->objects.push_back(obj);
        }

        file.close();

        return obj;
    }
}

问题在这里:
    __android_log_print(ANDROID_LOG_DEBUG,"path","%s",(path + "/info.txt").c_str());
    ifstream file((path + "/info.txt").c_str());
    if (!file.is_open()){
        //always enters here
        return Object(true);  //null object
    } else{
        //never enters here
        ...do stuff...
    }

在JNI方法中,我将info.txt文件所在的路径作为参数传递,但它无法打开它(没有错误,它只是进入了第一个if语句)。我首先尝试将文件夹放在我的手机sd卡中,之后放在我的内部存储中,但无论如何都不起作用。我在手机上检查了一下,我想路径是正确的:
链接到显示文件夹路径的图像 此外,我在Android清单中拥有读写外部存储权限。
您知道问题出在哪里或者是什么问题吗?
非常感谢!
编辑1:
将代码更改为以下内容:
__android_log_print(ANDROID_LOG_DEBUG,"path","%s",(path + "/info.txt").c_str());
ifstream file;
file.open((path + "/info.txt").c_str());
if (!file.is_open()){
    //always enters here
    return Object(true);  //null object
} else{
    //never enters here
    ...do stuff...
}

我仍然遇到同样的问题。

编辑2

我得到的日志结果如下(它们对应着正在尝试访问的路径):

D/path: /storage/emulated/0/TFG/Fotos/Carpeta/info.txt
D/path: /storage/emulated/0/TFG/Fotos/Cereales/info.txt

我的设备中,文件info.txt在该路径下:

照片


附上您正在使用的日志详细信息,尝试使用此方法http://stackoverflow.com/questions/20663467/jni-reading-a-text-file-in-c-code-and-returning-to-sdk。 - Pavneet_Singh
你的安卓手机是哪个版本?如果它的版本大于棒棒糖,请确保你已经实现了权限模型。 - Pavneet_Singh
@PavneetSingh添加了日志详细信息。我会尝试您发布的方法并告诉您,谢谢 :) PS:Android版本为6.0.1(棉花糖) - AMarquez94
你不需要更改代码,首先检查答案的更新部分,如果没有实现它。 - Pavneet_Singh
@PavneetSingh 嗯,我认为这可能是问题所在,因为我只在Android清单中拥有权限。我会查看并发布解决方案,如果我找到了的话。非常感谢 :) - AMarquez94
1个回答

7
< p > 文件尚未打开,您需要调用file.open()函数将流与当前文件关联,然后再进行is_open检查。< /p >
file.open();
 if (!file.is_open()){
        return Object(true); 
    }

更新:另一个可能的原因是您没有运行时权限模型。请参阅官方文档此链接中的精确示例


1
非常感谢!你的解答非常有效!(我已经给你点赞了,但是由于我的声望不足15分,所以无法显示,抱歉) - AMarquez94

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接