Search code examples
androidxamarinio

List all files opened by my Android App


I am intermittently getting Too many open files exceptions when I try to write to a text file in my Xamarin / Android app. I understand that this is because each Android app has a limit on the number of files it can have open, and obviously my app is exceeding it in some circumstances. Hence I must be leaving some files open / not disposing of them properly somewhere. I would like to know if I can programatically list the files that my app has open at any given time? Obviously the operating system knows this, is it possible to do this from within my app? This will help me find the problem.

Thanks to fiddler, this is how I solved it in case anyone else needs to do it in the future (in C# / Xamarin):

private static List<string> m_commandData;

    private static void GetOpenedFiles()
    {
        m_commandData = new List<string>();
        RunCommand("lsof");

        RunCommand("ps | grep TestNoFilesOpen");

    }

    private static void RunCommand(string command)
    {
        string data;
        using (Java.Lang.Process process = Java.Lang.Runtime.GetRuntime().Exec(command))
        {

            Stream stream = process.InputStream;

            StreamReader bodyReader = new StreamReader(stream);

            data = bodyReader.ReadToEnd();
        }
        m_commandData.Add(data);

    }

    private static void WriteCommands()
    {
        for (int i = 0; i < m_commandData.Count; i++)
        {

            using (TextWriter tw = new StreamWriter(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + "/NoFilesOpen/adb_" + i.ToString() + ".txt"))
            {
                tw.Write(m_commandData[i]);
                tw.Close();
            }
        }

        m_commandData = new List<string>();
    }

Solution

  • You could use the Unix lsof command in the ADB shell.

    1. Start the shell:

      $ adb shell

    2. Find the process ID of your app:

      shell@android:/ $ ps | grep <packagename>

    3. List files opened by your app:

      shell@android:/ $ lsof -p <pid>