Android: reading from text file – finished with exception open failed: ENOENT (No such file or directory)

huangapple go评论46阅读模式
英文:

Android: reading from text file - finished with exception open failed: ENOENT (No such file or directory)

问题

我是Android应用程序开发的新手(使用Java),我需要帮助。
我需要读取文本文件并将每一行存储到List中。
我在StackOverflow上阅读了许多讨论,其中一个启发了我的代码。但我无法解决我的问题...

所以我像下面这样调用文件选择器:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);

try {
    startActivityForResult(Intent.createChooser(intent, getString(R.string.vyber_soubor)), VYBER_SOUBORU_POZNAMKA);
} catch (android.content.ActivityNotFoundException ex) {
    Toast.makeText(kontext, "SeznamPoznamek::onCreate::tlPridej.setOnClickListener - 请安装文件管理器。", Toast.LENGTH_LONG).show();
}

并在onActivityResult函数中(下面只显示了必要部分,其余部分用点号标记)从意图中选择的文件的URI中提取文件路径。使用getPath函数从URI中提取文件路径字符串。然后,我将这个文件路径字符串发送到importujTextovouPoznamku函数中,我想从文本文件中读取行。但在FileInputStream fis = new FileInputStream(mujExterniSoubor);这一行会抛出异常("java.io.FileNotFoundException: /document/primary:DCIM/veci_svor.txt: open failed: ENOENT (No such file or directory)")。

在清单中是这样的:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

应用程序已经被授予写入存储的权限。

我对文件路径中有两个点感到惊讶(您可以在异常中看到我的文件路径字符串,那里也可以看到我的文件存储在DCIM文件夹中)。

对我来说,第二个惊喜是,在真实的手机Huawei honor 6A(Android 6)上,这段代码可以正常工作(但仅在这部手机上),但在其他手机Motorola e5 plus(Android 8)或虚拟机(Android 6或8)上无法工作。

请问有人可以帮助我或建议我如何在没有异常的情况下继续我的代码吗?谢谢 fik236

部分代码示例:

private String getPath(Uri uri) {
    String path = null;
    String[] projection = { MediaStore.Files.FileColumns.DATA };
    Cursor cursor = getContentResolver().query(uri, projection, null, null, null);

    if (cursor == null) {
        path = uri.getPath();
    } else {
        cursor.moveToFirst();
        int column_index = cursor.getColumnIndexOrThrow(projection[0]);
        path = cursor.getString(column_index);
        cursor.close();
    }

    return ((path == null || path.isEmpty()) ? (uri.getPath()) : path);
}

public void onActivityResult(int kodVolani, int vysledekVolani, Intent mujVraceciIntent) {
    super.onActivityResult(kodVolani, vysledekVolani, mujVraceciIntent);
    // ...
} else if (kodVolani == VYBER_SOUBORU_POZNAMKA) {
    Uri uri = mujVraceciIntent.getData();
    String src = getPath(uri);
    importujTextovouPoznamku(src);
}
// ...

public void importujTextovouPoznamku(String jmenoSouboru) {
    List<String> precteneRadky = new ArrayList<>();

    File mujExterniSoubor = new File(jmenoSouboru);
    try {
        FileInputStream fis = new FileInputStream(mujExterniSoubor); // 问题出在这里
        DataInputStream in = new DataInputStream(fis);
        BufferedReader br = new BufferedReader(new InputStreamReader(in));

        String radek;
        while ((radek = br.readLine()) != null) {
            precteneRadky.add(radek);
        }
        br.close();
        in.close();
        fis.close();
    } catch (IOException e) {
        e.printStackTrace();
        Toast.makeText(getBaseContext(), "SeznamPoznamek.java::prectiRadkyZeSouboru:" + e.getMessage(), Toast.LENGTH_LONG).show();
    }
    // ...
}

希望这可以帮助你解决问题。如果你需要更多的帮助,请随时告诉我。

英文:

I am new in Android apps development (java) and I need help.
I need read text file and store each line to List&lt;String&gt;.
I have read many discusions here in stackoverflow. One of them inspired my code. But I can not solve my problem ...

So I call file picker like bellow:

    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(&quot;*/*&quot;);
intent.addCategory(Intent.CATEGORY_OPENABLE);
try {                                
startActivityForResult(Intent.createChooser(intent, getString(R.string.vyber_soubor)), VYBER_SOUBORU_POZNAMKA);
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(kontext, &quot;SeznamPoznamek::onCreate::tlPridej.setOnClickListener - Please install a File Manager.&quot;, Toast.LENGTH_LONG).show();
}

and in function onActivityResult (bellow is shown only neccessary part, the rest of function is marked as dots) pick from intent uri of choosed file. With function getPath
extract from uri file-path as a string. This file-path string I send to function "importujTextovouPoznamku" where I want to read lines from text file.
But at line "FileInputStream fis = new FileInputStream(mujExterniSoubor);" is exception
("java.io.FileNotFoundException: /document/primary:DCIM/veci_svor.txt: open failed: ENOENT (No such file or directory)") threw

In manifest is:
&lt;uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

and app has permition to write into storage.

I am surprised that I have double dot in file path (you can see my file-path string in exception, there is also visible that my file is stored at DCIM folder)

And second surprise for me is that at real phone Huawei honor 6A (android 6) this code works (but only at this phone), but no at other phone Motorola e5 plus (android 8) or virtual machines (android 6 or 8).

Please could anybody help me or advice what I should try to continue in my code without exception
Thanks fik236

some part of code:

    private String getPath(Uri uri) {
String path = null;
String[] projection = { MediaStore.Files.FileColumns.DATA };
Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
if(cursor == null){
path = uri.getPath();
}
else{
cursor.moveToFirst();
int column_index = cursor.getColumnIndexOrThrow(projection[0]);
path = cursor.getString(column_index);
cursor.close();
}
return ((path == null || path.isEmpty()) ? (uri.getPath()) : path);
}
public void onActivityResult(int kodVolani, int vysledekVolani, Intent mujVraceciIntent) {
super.onActivityResult(kodVolani, vysledekVolani, mujVraceciIntent);
.
.
.
} else if ( kodVolani== VYBER_SOUBORU_POZNAMKA) {
Uri uri = mujVraceciIntent.getData();
String src = getPath(uri);
importujTextovouPoznamku(src);
}
.
.
.
public void importujTextovouPoznamku (String jmenoSouboru) {
List&lt;String&gt; precteneRadky = new ArrayList&lt;&gt;();
File mujExterniSoubor = new File(jmenoSouboru);
try {
FileInputStream fis = new FileInputStream(mujExterniSoubor); //problem
DataInputStream in = new DataInputStream(fis);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String radek;
while ((radek = br.readLine()) != null) {
precteneRadky.add(radek);
}
br.close();
in.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getBaseContext(),&quot;SeznamPoznamek.java::prectiRadkyZeSouboru:&quot; + e.getMessage(), Toast.LENGTH_LONG).show();
}
.
.
.

答案1

得分: 1

不要尝试从 URI 获取路径,以打开该路径的 FileInputStream。最好直接为 URI 打开一个 InputStream。

InputStream is = getContentResolver().openInputStream(data.getData());

然后像处理文件一样从 is 中读取
英文:

Do not try to get a path from an uri with the intention to open a fileinputstream for that path. Better open an inputstream for the uri directly.

InputStream is = getContentResolver().openInputStream(data.getData());

Then read from is as it was your fis.

huangapple
  • 本文由 发表于 2020年8月2日 01:44:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/63208269.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定