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