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
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.
There's the way of IOUtils:
copy(InputStream input, OutputStream output)
The code of it is similar to this :
public static long copyStream(InputStream input, OutputStream output) throws IOException {
long count = 0L;
byte[] buffer = new byte[4096];
for (int n; -1 != (n = input.read(buffer)); count += (long) n)
output.write(buffer, 0, n);
return count;
}
A shorter version:
OutputStream out = new FileOutputStream(file);
fos.write(IOUtils.read(in));
out.close();
in.close();
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
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();
}
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();
}
}
}