How to write a file to app specific directory?

I made a post a while back but the question went unanswered. The problem I am having still persists and I am not sure how to solve it. The problem is that I am trying to write a file to my app specific directory but when I write the file it does not save to the app directory. I also tried the snippet of code on Link but I keep getting a Unresolved reference: context.

Here is my code:

            val file = "code.py"
            val fileOutputStream: FileOutputStream
            //Creating LinkedList object
            val list: MutableCollection<String> = LinkedList()
            //Adding the Opcodes to the linkedlist
            list.add("SS;")
            list.add("BN(=X=5);")
            list.add("BN(=Y=7);")
            list.add("CS0507(=Y);")
            list.add("BG(=7=5)Y;")
            list.add("BL(=A=360);")
            list.add("BL(=B=360);")
            list.add("CQ(=5000);")
            list.add("CG(=A);")
            list.add("CG(=B);")
            list.add("XX;")
            try
            {
                //Creating the python file
                fileOutputStream = openFileOutput(file, Context.MODE_PRIVATE)
                //Incrementing through the list and writing to the file
                for(item in list)
                {
                    //Creating LookUp object
                    val opcode = LookUp()
                    var code: String = ""
                    //Function call to match Opcodes from linkedlist
                    code = opcode.match(item)

                    //Writing python code to file
                    fileOutputStream.write(code.toByteArray())
                }
            }
            //Catching any file errors that could occur
            catch(e: FileNotFoundException)
            {
                e.printStackTrace()
            }
            catch(e:NumberFormatException)
            {
                e.printStackTrace()
            }
            catch(e: IOException)
            {
                e.printStackTrace()
            }
            catch(e:Exception)
            {
                e.printStackTrace()
            }
            //Creating display message when generating the code
            Toast.makeText(this, "Generating", Toast.LENGTH_SHORT).show()

I also tried the method given on the android documentation but I keep getting errors such as Unresolved reference: context, Unresolved reference: write

val fileName = "code.py"
            val file = File(context.filesDir, fileName)
            val fileOutputStream: FileOutputStream
            //Creating LinkedList object
            val list: MutableCollection<String> = LinkedList()
            //Adding the Opcodes to the linkedlist
            list.add("SS;")
            list.add("BN(=X=5);")
            list.add("BN(=Y=7);")
            list.add("CS0507(=Y);")
            list.add("BG(=7=5)Y;")
            list.add("BL(=A=360);")
            list.add("BL(=B=360);")
            list.add("CQ(=5000);")
            list.add("CG(=A);")
            list.add("CG(=B);")
            list.add("XX;")
            try
            {
                //Creating the python file
                context.openFileOutput(fileName, Context.MODE_PRIVATE).use{
                    for(item in list)
                    {
                        //Creating LookUp object
                        val opcode = LookUp()
                        var code: String = ""
                        //Function call to match Opcodes from linkedlist
                        code = opcode.match(item)

                        //Writing python code to file
                        it.write(code.toByteArray())
                    }
                }
                //Incrementing through the list and writing to the file

            }
            //Catching any file errors that could occur
            catch(e: FileNotFoundException)
            {
                e.printStackTrace()
            }
            catch(e:NumberFormatException)
            {
                e.printStackTrace()
            }
            catch(e: IOException)
            {
                e.printStackTrace()
            }
            catch(e:Exception)
            {
                e.printStackTrace()
            }
            //Creating display message when generating the code
            Toast.makeText(this, "Generating", Toast.LENGTH_SHORT).show()

Any assistance is appreciated

Do you verify that this code is at all executed? How do you observe that the file was not created?

Thanks for replying. I did check to see if the file was created in the device manager on Android Studio. Its created in the data/data/com.gadgetboxv3/files directory. However, when I look for the file on my device it’s not there.

What do you mean by “when I look for the file on my device”? So far you only provided the proof that the file exists, but I’m still not sure how do you observe that it doesn’t :slight_smile:

These are screenshots from my phone on which the application is installed.




The code.py file isn’t in any of these folders.

I didn’t develop for Android for a long time, but I believe you’re just looking at different directories. You wrote the file to the internal storage and you can’t access this storage in any other way than from the app itself. What you see at screens from your last post is the external storage, accessible to other apps.

Documentation linked by you is very clear about this:

Internal storage directories: These directories include both a dedicated location for storing persistent files, and another location for storing cache data. The system prevents other apps from accessing these locations, and on Android 10 (API level 29) and higher, these locations are encrypted. These characteristics make these locations a good place to store sensitive data that only your app itself can access.

1 Like

I managed to create a file using the same method I used to create the pictures I take with my camera.

private fun createCodeFile(): File
    {
        val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
        val storageDir: File? = getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS)
        return File.createTempFile("Code_${timeStamp}_", ".py", storageDir).apply {
            currentCodePath = absolutePath
        }
    }

This file appears in the app directory but when I am trying to write the data to it, there’s nothing in the file. Do you know how to write to a file that has already been created?

Updated Code with the creation of the file.

val file = "code.py"
            val fileOutputStream: FileOutputStream
            //Creating LinkedList object
            val list: MutableCollection<String> = LinkedList()
            //Adding the Opcodes to the linkedlist
            list.add("SS;")
            list.add("BN(=X=5);")
            list.add("BN(=Y=7);")
            list.add("CS0507(=Y);")
            list.add("BG(=7=5)Y;")
            list.add("BL(=A=360);")
            list.add("BL(=B=360);")
            list.add("CQ(=5000);")
            list.add("CG(=A);")
            list.add("CG(=B);")
            list.add("XX;")
            try
            {
                //Creating the python file
                codeFile = createCodeFile()
                val writer = FileWriter(codeFile)
                val uriCode = FileProvider.getUriForFile(this, "com.gadget.gadgetboxv3.fileprovider", codeFile)
                fileOutputStream = openFileOutput(file, Context.MODE_PRIVATE)
                //Incrementing through the list and writing to the file
                for(item in list)
                {
                    //Creating LookUp object
                    val opcode = LookUp()
                    var code: String = ""
                    //Function call to match Opcodes from linkedlist
                    code = opcode.match(item)

                    //Writing python code to file
                    writer.write(code)
                    writer.flush()
                    writer.close()
                    fileOutputStream.write(code.toByteArray())
                }
            }
            //Catching any file errors that could occur
            catch(e: FileNotFoundException)
            {
                e.printStackTrace()
            }
            catch(e:NumberFormatException)
            {
                e.printStackTrace()
            }
            catch(e: IOException)
            {
                e.printStackTrace()
            }
            catch(e:Exception)
            {
                e.printStackTrace()
            }
            //Creating display message when generating the code
            Toast.makeText(this, "Generating", Toast.LENGTH_SHORT).show()

Honestly, I would expect this code to throw an exception, because you write to writer after you close it. Did you look into logs? Also, I have no idea what is opcode.match(), maybe it returns empty string?

I think you need to learn how to debug your code and analyze its behavior. Otherwise it is basically guessing.

Is the writer and FileOutputStream objects not two different things? opcode.match() returns a string from a lookup table. This string that is returned is written to the file that I can only access from the device manager on Android Studio so I know that the string is definitely not empty. I am new to Android Studio and Kotlin so I’m still learning how to use all the features on the IDE.

You may get better answers on Stackoverflow.com, this question is not about kotlin language, but about Android file permissions.