question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

java.io.FileNotFoundException

See original GitHub issue
E/LogWriter: save: 
 java.io.FileNotFoundException: /data/com.github.piasy.bootstrap/performance/looper-2016-12-11_23-48-25.844.log (No such file or directory)
     at java.io.FileOutputStream.open(Native Method)
     at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
     at java.io.FileOutputStream.<init>(FileOutputStream.java:140)
     at com.github.moduth.blockcanary.LogWriter.save(LogWriter.java:108)
     at com.github.moduth.blockcanary.LogWriter.save(LogWriter.java:56)
     at com.github.moduth.blockcanary.BlockCanaryInternals$1.onBlockEvent(BlockCanaryInternals.java:63)
     at com.github.moduth.blockcanary.LooperMonitor$1.run(LooperMonitor.java:74)
     at android.os.Handler.handleCallback(Handler.java:751)
     at android.os.Handler.dispatchMessage(Handler.java:95)
     at android.os.Looper.loop(Looper.java:154)
     at android.os.HandlerThread.run(HandlerThread.java:61)

Issue Analytics

  • State:open
  • Created 7 years ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

5reactions
zjupurecommented, Dec 20, 2016

@Piasy this problem is produced when the external storage is not available or not writable. For example, the external storage is unmounted and it is really exist in some devices. When external storage is not exist, the library with choose the /data/{your_provided_dir}, but this directory is not accessible by normal app due to permission limit. the code in BlockCanaryInternals.getPath() have some drawback in design.

static String getPath() {
        String state = Environment.getExternalStorageState();
        String logPath = BlockCanaryInternals.getContext()
                == null ? "" : BlockCanaryInternals.getContext().providePath();

        if (Environment.MEDIA_MOUNTED.equals(state)
                && Environment.getExternalStorageDirectory().canWrite()) {
            return Environment.getExternalStorageDirectory().getPath() + logPath;
        }
        return Environment.getDataDirectory().getAbsolutePath() + BlockCanaryInternals.getContext().providePath();
    }

There is another permission problem, the external storage is not writeable default except the app-specifical directory due to the dynamic permission mechanism since Android 6.0. So i suggest BlockCanary library can modify the implementation of BlockCanaryInternals.getPath(), there are two choice:

  1. the path is provided entirely by user through BlockCanaryContext.providePath(), the path validation is decided by user.
  2. change the external storage directory to app-specifical directory, when this path is not avaiable, use the internal storage directory instead.

App-specifical directory usually locates in external storage /Android/data/{pacakage_name}, you can use Context.getExternalCacheDir() or Context.getExternalFilesDir() to obtain a cache directory(/cache) or a files directory(/files). Those directory do not need to declare permission in Android Mainifest since Kitkat. If abvoe path is not avaiable (external storage is unmount), use Context.getCacheDir() or Context.getFilesDir() instead. The result are usually located in /data/data/{pacakage_name} in internal storage and always available to normal app.

A reference implementation for choice 2

static String getPath() {
        String state = Environment.getExternalStorageState();
        String logPath = BlockCanaryInternals.getContext()
                == null ? "" : BlockCanaryInternals.getContext().providePath();

        Context context = BlockCanaryInternals.getContext().provideContext();
        File appCache = context.getExternalCacheDir();
        if (appCache != null && Environment.MEDIA_MOUNTED.equals(state)) {
            return  appCache.getAbsolutePath() + logPath;
        }
        return context.getCacheDir() + logPath;
    }
0reactions
markzhaicommented, Jan 4, 2017

@initialjie @zjupure thanks, I adopt that the path should be provided entirely by user, the library itself should not do any magic to it.

Read more comments on GitHub >

github_iconTop Results From Across the Web

java.io.FileNotFoundException in Java - GeeksforGeeks
java.io.FileNotFoundException which is a common exception which occurs while we try to access a file. FileNotFoundExcetion is thrown by ...
Read more >
How to Fix the FileNotFoundException in Java.io - Rollbar
The FileNotFoundException is a checked exception in Java that occurs when an attempt to open a file denoted by a specified pathname fails....
Read more >
java.io.FileNotFoundException: the system cannot find the file ...
First thing you would need to do (in this particular) case is make sure that the file get built into the classpath. With...
Read more >
FileNotFoundException (Java Platform SE 8 )
Signals that an attempt to open the file denoted by a specified pathname has failed. This exception will be thrown by the FileInputStream...
Read more >
Solving java.io.FileNotFoundException
java.io.filenotfoundexception is thrown during a failed attempt to open the file denoted by a specified pathname.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found