0

I want to get details about a selected harbour,by taking val s from a list extracted using readLines from a .txt file, where each harbour has a .txt file in the assets directory. I generate the file name but when the app is run in the emulator I get a file not found error. In this case I am trying to get at a file called Brehatharm.txt

 var portChosen = "Brehat"
        //"tide2a/app/src/main/assets/"+//various paths to try 
fileName = "assets/"+portChosen+"harm.txt"
val harmConsList:List<String> = File(fileName).readLines()

        val portDisplayName = harmConsList[0]
        val longTude = harmConsList[1]
        val MTL =harmConsList[2]
etc,

The log cat reads :-

2021-01-10 15:40:34.044 7108-7108/com.example.tide2a E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.tide2a, PID: 7108
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.tide2a/com.example.tide2a.MainActivity}: java.io.FileNotFoundException: assets/Brehatharm.txt: open failed: ENOENT (No such file or directory)

The full windows path to the file is :- C:\Users.......\OneDrive\Coding projects\tide2a\app\src\main\assets\Brehatharm.txt

I am sure the file is there, and spelled correctly, so I suspect I am specifying the path incorrectly. Please advise me.

JJCNSNR
  • 9
  • 3

1 Answers1

0

Files in assets/ cannot be accessed using the File class. Use context.assets to get the AssetManager, and you can open InputStreams to the files.

Tenfour04
  • 83,111
  • 11
  • 94
  • 154
  • I read the Files documentation and to me it looks as though Files could read the .txt file if I specified the full winodws/Linux path, but that's not going to any good as I cant be sure they will be available in the same location on other devices. I am trying FileReader and BufferedReader – JJCNSNR Jan 11 '21 at 13:56
  • AFAIK, there is no way to know the file path at compile time to be able to use the File class to access a file packaged with your app. The rubric for determining the absolute path may differ between Android versions and maybe even phone models. What are you trying to do that can't be done with InputStream? You could use the InputStream of a file in `/assets` to write a copy of it to a file in internal storage and then use the File class to access it from there. Android provides `context.filesDir` to get the parent path to the internal directory that you can pass to the File constructor. – Tenfour04 Jan 11 '21 at 14:21
  • TBH I don't know enough about context, or InputStream, and I have been trying to find simple ways to avoid them. I'm not succeeding so I will just have to go back to studying. Thanks for your help – JJCNSNR Jan 12 '21 at 16:45
  • Context is foundational to anything on Android, so you'll have to learn what that is ASAP. You can read from an InputStream pretty easily: `context.assets.open(fileName).bufferedReader().readLines()` is equivalent to what you were trying to do with `File` in your code above. – Tenfour04 Jan 12 '21 at 18:46