Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I have been getting a
java.io.IOException: Not a directory
exception for the following code:
fun saveImage(IdNumber: Int, photoFile: File, plantType: Int) {
val newImage = PlantPhoto(IdNumber, "ZZ Plant", photoFile, plantType)
val dir = File(
context.getExternalFilesDir("planio/dataclasses/${plantType}").toString()
if (!dir.exists()) {
dir.mkdirs()
val dataClassLocation = File(dir, "$IdNumber")
if (dataClassLocation.exists()) {
dataClassLocation.delete()
dataClassLocation.createNewFile()
} else{
//exception occurs here
dataClassLocation.createNewFile()
val plantFile = FileOutputStream(dataClassLocation, true)
val outStream = ObjectOutputStream(plantFile)
outStream.writeObject(newImage)
outStream.close()
plantFile.close()
Log.i(SaveTag, "Image saved successfully")
I have already checked that parent directories exist and since I am using an emulator that runs on API 29, getExternalFilesDir
should not require permission to read and write to. But I am unsure as to why I am getting this exception since I should be able to create a new File inside another File as per this link.
Here is the stack trace:
Caused by: java.io.IOException: Not a directory
at java.io.UnixFileSystem.createFileExclusively0(Native Method)
at java.io.UnixFileSystem.createFileExclusively(UnixFileSystem.java:317)
at java.io.File.createNewFile(File.java:1008)
at com.example.camera.presentation.CameraViewModel.saveImage(CameraViewModel.kt:68)
at com.example.camera.presentation.CameraFragment$takePhoto$1.onImageSaved(CameraFragment.kt:167)
at androidx.camera.core.ImageCapture$3.onImageSaved(ImageCapture.java:661)
at androidx.camera.core.ImageSaver.lambda$postSuccess$0$ImageSaver(ImageSaver.java:253)
at androidx.camera.core.-$$Lambda$ImageSaver$-JRZLUaKK7DQ1iBdZ_1qTGbYQrk.run(Unknown Source:4)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Using @ALUFTW 's answer, I have modified my code to this:
fun saveImage(IdNumber: Int, photoFile: File, plantType: Int) {
val newImage = PlantPhoto(IdNumber, "ZZ Plant", photoFile, plantType)
val dataClassLocation = File(context.getExternalFilesDir("planio/dataclasses/${plantType}/$IdNumber").toString())
if (!dataClassLocation.exists()) {
try {
dataClassLocation.parentFile.mkdirs()
dataClassLocation.createNewFile()
} catch (e: IOException) {
e.printStackTrace()
val plantFile = FileOutputStream(dataClassLocation, true)
val outStream = ObjectOutputStream(plantFile)
// Method for serialization of object
outStream.writeObject(newImage)
outStream.close()
plantFile.close()
Log.i(SaveTag, "Image saved successfully")
And now I am getting a new java.io.FileNotFoundException: planio/dataclasses/1/filename: open failed: ENOENT (No such file or directory)
–
–
–
–
The line dir.mkdirs()
isn't creating a directory for you.
If it won't work- It will not throw exception but it will return false.
Try the following code:
File dataClassLocation_folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/planio/dataclasses/${plantType}/");
dataClassLocation_folder.mkdirs();
File dataClassLocation_file = new File(dataClassLocation_folder,filename);
dataClassLocation_file.createNewFile();
–
–
–
I have now separated my subdirectories and my code is working :)
Turns out it is not allowed to put a whole subdirectories train as parameter in getExternalFilesDir
.
fun saveImage(IdNumber: Int, photoFile: File, plantType: Int) {
val newImage = PlantPhoto(IdNumber, "ZZ Plant", photoFile, plantType)
val dir = File(
context.getExternalFilesDir(null), "planio/dataclasses"
if (!dir.exists()) {
dir.mkdirs()
val dirOne = File(dir, "$plantType")
if(!dirOne.exists()){
dir.mkdirs()
val dataClassLocation = File(dirOne, "$IdNumber")
if (dataClassLocation.exists()) {
dataClassLocation.delete()
dataClassLocation.createNewFile()
} else{
dataClassLocation.createNewFile()
val plantFile = FileOutputStream(dataClassLocation, true)
val outStream = ObjectOutputStream(plantFile)
outStream.writeObject(newImage)
outStream.close()
plantFile.close()
Log.i(SaveTag, "Image saved successfully")
Replace:
val dir = File(
context.getExternalFilesDir("planio/dataclasses/${plantType}").toString()
with:
val dir = File(
context.getExternalFilesDir(null), "planio/dataclasses/${plantType}"
...and see if you have better luck. The parameter to getExternalFilesDir()
is a Directory type (downloads, pictures, audio, etc) returning the root of the path from the environment, not a subdirectory path, this one you must create inside the root.
–
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.