Home > Net >  Simple question about File class in kotlin
Simple question about File class in kotlin

Time:03-01

I'm trying to read from a file in kotlin using the File class. It's just a simple txt file with a list of names with each name occupying an independent row. This is my project structure: enter image description here

and here's my function for pulling out a name depending on the day of the year:

private fun getNameOfTheDay(): String {
        val cal = Calendar.getInstance()
        val day = cal[Calendar.DATE]

        return File("data${File.separator}names.txt")
            .bufferedReader()
            .lineSequence()
            .elementAt(day - 1)
    }

I keep on getting a FileNotFound exception so I would assume that my file path is somehow wrong... What am I doing wrong here? Sorry for the dumb question, I'm still learning. By the way the function shown above is called from the MainActivity. Thanks in Advance!

CodePudding user response:

You should try "data\names.txt". Oftentimes slashes don't work for file paths.

CodePudding user response:

Filenames can be absolute or relative. Absolute filenames start from the top level (e.g. the root directory on Unix-like filesystems, which Macs have; or a drive letter on Windows), and so specify the filename unambiguously. Relative filenames don't, and so give a file in (or in relation to) the current working directory.

In this case, data/names.txt is a relative filename. It assumes that the current directory has a subdirectory called data, and refers to a file in that.

However, the file is actually in the directory app/src/main/java/com/example/mynameis/data/ within your project — so this would only work if the current directory was /<pathToYourProject/app/src/main/java/com/example/mynameis/, which is highly unlikely! So that probably explains the failure.

I don't know about Android projects, but in normal JVM projects the standard practice is to put data files in a src/main/resources/ directory. Gradle (or Maven) knows to copy them into the classpath when building the project. You would then load it from the classpath, e.g. with:

javaClass.getResource("data/names.txt").readText()

See e.g. this question for more details and variations.

The advantage of loading from the classpath instead of a file is that you don't need to know exactly where the file is; it could be loose on the filesystem, or bundled into a jar or other archive (even compressed), with ways to select between different versions depending on the run profile — all completely transparent to your code.

As I said, I don't know Android, and can't find any direct answers on StackOverflow. (This question seems to suggest using a android.resource:// URI, but I don't know if that would apply here.) Maybe these external sites can give you some hints.

  • Related