Android - Store inputstream in file
Solution 1
Here it is, input is your inputStream
. Then use same File (name) and FileInputStream
to read the data in future.
try {
File file = new File(getCacheDir(), "cacheFileAppeal.srl");
try (OutputStream output = new FileOutputStream(file)) {
byte[] buffer = new byte[4 * 1024]; // or other buffer size
int read;
while ((read = input.read(buffer)) != -1) {
output.write(buffer, 0, read);
}
output.flush();
}
} finally {
input.close();
}
Solution 2
Simple Function
Try this simple function to neatly wrap it up in:
// Copy an InputStream to a File.
//
private void copyInputStreamToFile(InputStream in, File file) {
OutputStream out = null;
try {
out = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len;
while((len=in.read(buf))>0){
out.write(buf,0,len);
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
// Ensure that the InputStreams are closed even if there's an exception.
try {
if ( out != null ) {
out.close();
}
// If you want to close the "in" InputStream yourself then remove this
// from here but ensure that you close it yourself eventually.
in.close();
}
catch ( IOException e ) {
e.printStackTrace();
}
}
}
Thanks to Jordan LaPrise and his answer.
Solution 3
Kotlin version (tested and no library needed):
fun copyStreamToFile(inputStream: InputStream, outputFile: File) {
inputStream.use { input ->
val outputStream = FileOutputStream(outputFile)
outputStream.use { output ->
val buffer = ByteArray(4 * 1024) // buffer size
while (true) {
val byteCount = input.read(buffer)
if (byteCount < 0) break
output.write(buffer, 0, byteCount)
}
output.flush()
}
}
}
We take advantage of use
function which will automatically close both streams at the end.
The streams are closed down correctly even in case an exception occurs.
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/use.html
https://kotlinlang.org/docs/tutorials/kotlin-for-py/scoped-resource-usage.html
Solution 4
A shorter version:
OutputStream out = new FileOutputStream(file);
fos.write(IOUtils.read(in));
out.close();
in.close();
Solution 5
Here is a solution which handles all the Exceptions and is based on the previous answers:
void writeStreamToFile(InputStream input, File file) {
try {
try (OutputStream output = new FileOutputStream(file)) {
byte[] buffer = new byte[4 * 1024]; // or other buffer size
int read;
while ((read = input.read(buffer)) != -1) {
output.write(buffer, 0, read);
}
output.flush();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Admin
Updated on July 05, 2022Comments
-
Admin almost 2 years
I am retrieveing an XML feed from a url and then parsing it. What I need to do is also store that internally to the phone so that when there is no internet connection it can parse the saved option rather than the live one.
The problem I am facing is that I can create the url object, use getInputStream to get the contents, but it will not let me save it.
URL url = null; InputStream inputStreamReader = null; XmlPullParser xpp = null; url = new URL("http://*********"); inputStreamReader = getInputStream(url); ObjectOutput out = new ObjectOutputStream(new FileOutputStream(new File(getCacheDir(),"")+"cacheFileAppeal.srl")); //-------------------------------------------------------- //This line is where it is erroring. //-------------------------------------------------------- out.writeObject( inputStreamReader ); //-------------------------------------------------------- out.close();
Any ideas how I can go about saving the input stream so I can load it later.
Cheers
-
amitavk over 8 yearsNesting try blocks though?
-
Volodymyr Lykhonis over 8 yearsException can happen anytime if so you will leak system resources.
-
gMale about 7 yearsbecause it requires IOUtils from Apache commons and that's a heavy weight dependency to add to a mobile app. Most people would rather a solution that relies on standard SDK classes.
-
jk7 about 7 yearsout.close() should be in a finally {} block to avoid leaking resources if an exception occurs. Same for in.close() if it performed here, though it is really the responsibility of the caller to close it.
-
Joshua Pinter about 7 years@jk7 You're probably right actually. Take a look at the updated answer.
-
Tim Kist over 6 yearsFor testing (
test
andandroidTest
artifacts), it's fine because it won't get included in app. -
Hack06 about 6 yearsThe "input" variable is an instance of InputStream, not InputStreamReader.
-
CoolMind almost 5 yearsSorry, what, if an exception oocurs (for instance, disconnection), can we rethrow the exception to an upper level?
-
CodeToLife almost 3 yearsi put
implementation 'commons-io:commons-io:2.5
,synced, but it showsimport org.apache.commons.io.FileUtils;
's FileUtils in red? -
Fahad-Android almost 2 yearsI keep getting "File is empty" exception