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:
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.