Android Studio - Read-Only Filesystem? - java

I am trying to write a file to internal device storage on my phone (and on user's phones in the future). I was watching a video tutorial from 2016 (https://www.youtube.com/watch?v=EhBBWVydcH8) which shows how he writes output to a file very simply. If you want to see his code, skip forward to 8:23.
Anyway, I basically tried his code, then since that didn't work, I figured would search around.
Apparently, to create a file, I need these lines of code:
String filename = "textfile.txt";
File file = new File(filename);
file.mkdirs();
file.createNewFile();
On the second line, file.createNewFile(), I get the below error:
java.io.IOException: Read-only file system
at java.io.UnixFileSystem.createFileExclusivel
at java.io.UnixFileSystem.createFileExclusivel
at java.io.File.createNewFile(File.java:948)
etc......
And then, if I run my code just by using the lines of code from the tutorial, I get a Null pointer.
Code:
try {
FileOutputStream fos = openFileOutput(filename, Context.MODE_PRIVATE);
fos.write(IDNum.getBytes());
fos.close();
System.out.println("Wrote STuff Outputtt?");
} catch (Exception e) {
e.printStackTrace();
}
Error:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.FileOutputStream android.content.Context.openFileOutput(java.lang.String, int)' on a null object reference
at android.content.ContextWrapper.openFileOutput(ContextWrapper.java:199)
at com.lecconnect.lockoutdemo.FileManager.AddUser(FileManager.java:37)
Line 37 is the first line in the try/catch.
Please let me know if you require any additional information to assist me. Your replies are greatly appreciated.

It is important to separate the directory and the file itself.
In your code, you call mkdirs on the file you want to write, which is incorrect usage because mkdirs makes your file into a directory. You should call mkdirs for the directory only, so it will be created if it does not exist, and the file will be created automatically when you create a new FileOutputStream object for this file.
Try this one:
File directory = getFilesDir(); //or getExternalFilesDir(null); for external storage
File file = new File(directory, fileName);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
fos.write(IDNum.getBytes());
fos.close();
} catch (IOException e) {
e.printStackTrace();
}

Related

Creating a new directory inside Android internal memory and writing data to it

Most of the examples I have seen deal with external memory or show how to create a new directory inside internal memory but not how to write to it, I tried implementing my own code into it but can't seem to find the created file even though the directory has been created, here is the code that I have been trying to use:
public void fileCreate(Context context, String fileDir) throws Exception{
File myNewDir = context.getDir(fileDir, Context.MODE_PRIVATE);
if (!myNewDir.exists()){
myNewDir.mkdirs();
File testContnet = new File(myNewDir + "/hello_file.txt");
String hello = "Hello world";
FileOutputStream fos = openFileOutput(testContnet.toString(), Context.MODE_PRIVATE);
fos.write(hello.getBytes());
fos.close();
}
}
Now, when I call this function I use:
try {
fileCreate(this, "testerDirectory");
}catch(Exception e) {
e.printStackTrace();
}
With no results. It is just for a small experiment I am doing so it is nothing too serious, but I still want to know about the proper way of creating a directory(in this case one called testerDirectory, and saving the file to it, I believe that my code is wrong but I do not have much experience with this to know exactly where to go. The Android documentation did show me how to create and save files although in this case I am trying to merge that example with that of creating a new directory and saving a file to it. Any help/pointers would be greatly appreciated.
I know also that the file is not being written accordingly upon inspecting the contents of the directory by using the adb shell.
You are only writing a file to the directory if the directory does not already exist.
Move your work with testContnet to be outside of the if block:
public void fileCreate(Context context, String fileDir) throws Exception{
File myNewDir = context.getDir(fileDir, Context.MODE_PRIVATE);
if (!myNewDir.exists()){
myNewDir.mkdirs();
}
File testContnet = new File(myNewDir, "hello_file.txt");
String hello = "Hello world";
FileOutputStream fos = new FileOutputstream(testContnet);
fos.write(hello.getBytes());
fos.flush();
fos.getFD().sync();
fos.close();
}
This way, you create the directory if it does not exist, but then create the file in either case. I also added fos.flush() and fos.getFD().sync(), to ensure all bytes get written to disk before you continue.
UPDATE: You were using openFileOutput(), which does not write to your desired directory. Moreover, it is unnecessary. Just create a FileOutputStream on your File.

How to download monthly Treasury Files

Up till early this year the US Treasury web site posted monthly US Receipts and Outlays data in txt format. It was easy to write a program to read and store the info. All I use were:
URL url = new URL("https://www.fiscal.treasury.gov/fsreports/rpt/mthTreasStmt/mts1214.txt")
URLConnection connection.openConnection();
InputStream is = connection.getInputStream();
Then I just read the InputStream into a local file.
Now when I try same code, for May, I get an InputStream with nothing in it.
Just clicking on "https://www.fiscal.treasury.gov/fsreports/rpt/mthTreasStmt/mts0415.xlsx" opens an excel worksheet (the download path has since changed).
Which is great if you don't mind clicking on each link separately ... saving the file somewhere ... opening it manually to enable editing ... then saving it again as a real .xlsx file (because they really hand you an .xls file.)
But when I create a URL from that link, and use it to get an InputStream, the is empty. I also tried url.openStream() directly. No different.
Can anyone see a way I can resume using a program to read the new format?
In case its of interest I now use this code to write the stream to the file bit by bit... but there are no bits, so I don't know if it works.
static void copyInputStreamToFile( InputStream in, File file ) {
try {
OutputStream out = new FileOutputStream(file);
byte[] buf = new byte[1024];
System.out.println("reading: " + in.read(buf));
//This is what tells me it is empty, i.e. the loop below is ignored.
int len;
while((len=in.read(buf))>0){
out.write(buf,0,len);
}
out.close();
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Any help is appreciated.

Unable to write to the Internal Storage

Please have a look at the following code
File folder = new File("/Main Note/Sub Notes/"+dateStr+"/");
File file = new File(folder+name.getText().toString()+".txt");
try
{
if(!folder.exists())
{
folder.mkdirs();
}
FileOutputStream outputStream = openFileOutput(file.getName(),Context.MODE_WORLD_WRITEABLE);
outputStream.write(spokenText.getBytes());
outputStream.flush();
outputStream.close();
Toast.makeText(VoiceNotes.this, "Data Successfully written to: "+file.getAbsolutePath(), Toast.LENGTH_LONG).show();
}
catch(IOException io)
{
Toast.makeText(VoiceNotes.this, "Error in Writing to SD", Toast.LENGTH_LONG).show();
}
Here I am trying to write data to the internal memory. This has no errors, displays the data has been written successfully.
But when I navigate to the Internal SD in phone, I don't see any folder or file it created! I guess I have done something wrong, this is the first time I am writing to the internal storage in Android.
File folder = new File(context.getFilesDir(),"/MyFolder/");
files will be created in "/data/data/app.package/files/...". But you can see them only if device was rooted
You want to access the path returned by getExternalStorageDirectory() as described here.

FileNotFoundException on FileOutputStream in spite of mkdirs() and createNewFile()

I have a bean that download emails from SMTP server. After read emails it saves attachments on the server. To read attachment I use this code:
File f = new File("\\attachments\\" + attachment.getFileName());
f.mkdirs();
f.createNewFile();
FileOutputStream fos = new FileOutputStream(f);
fos.write(bytes);
fos.close();
I got a FileNotFoundException on FileOutputStream creating and I can't understand why.
If can help, I use NetBeans with GlassFish and the tests are made in debug in local machine.
When you do
f.mkdirs();
You are creating a directory with the name of your file (that is, you create not only the directory "attachments", you also create a subdirectory with the name of your attachment filename). Then
f.createNewFile();
does not do anything since the file already exist (in the form of a directory you just created). It returns false to tell you that the file already exists.
Then this fails:
FileOutputStream fos = new FileOutputStream(f);
You are trying to open an output stream on a directory. The system doesn't allow you to write in a directory, so it fails.
The bottom line is:
mkdirs() doesn't do what you think it does.
you should check the return value of your call to createNewFile().
The simplest way to make it work is by replacing your line with:
f.getParentFile().mkdirs();

Get FileNotFoundException when initialising FileInputStream with File object

I am trying to initialise a FileInputStream object using a File object. I am getting a FileNotFound error on the line
fis = new FileInputStream(file);
This is strange since I have opened this file through the same method to do regex many times.
My method is as follows:
private BufferedInputStream fileToBIS(File file){
FileInputStream fis = null;
BufferedInputStream bis =null;
try {
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bis;
}
java.io.FileNotFoundException: C:\dev\server\tomcat6\webapps\sample-site (Access is denied)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.(Unknown Source)
at java.io.FileInputStream.(Unknown Source)
at controller.ScanEditRegions.fileToBIS(ScanEditRegions.java:52)
at controller.ScanEditRegions.tidyHTML(ScanEditRegions.java:38)
at controller.ScanEditRegions.process(ScanEditRegions.java:64)
at controller.ScanEditRegions.visitAllDirsAndFiles(ScanEditRegions.java:148)
at controller.Manager.main(Manager.java:10)
Judging by the stacktrace you pasted in your post I'd guess that you do not have the rights to read the file.
The File class allows you to performs useful checks on a file, some of them:
boolean canExecute();
boolean canRead();
boolean canWrite();
boolean exists();
boolean isFile();
boolean isDirectory();
For example, you could check for: exists() && isFile() && canRead() and print a better error-message depending on the reason why you cant read the file.
You might want to make sure that (in order of likely-hood):
The file exists.
The file is not a directory.
You or the Java process have permissions to open the file.
Another process doesn't have a lock on the file (likely, as you would probably receive a standard IOException instead of FileNotFoundException)
This is has to do with file permissions settings in the OS. You've started the java process as a user who has no access rights to the specific directory.
I think you are executing the statement from eclipse or any java IDE and target file is also present in IDE workspace. You are getting the error as Eclipse cant read the target file in the same workspace. You can run your code from command prompt. It should not through any exception.

Categories