Android - 将输入流存储在文件中

Dob*_*bes 52 android input stream

我正在从URL检索XML feed然后解析它.我需要做的是将内部存储到手机中,这样当没有互联网连接时,它可以解析保存的选项而不是实时选项.

我面临的问题是我可以创建url对象,使用getInputStream来获取内容,但它不会让我保存它.

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();
Run Code Online (Sandbox Code Playgroud)

任何想法如何保存输入流,以便我以后加载它.

干杯

Vol*_*nis 92

在这里,输入是你的inputStream.然后使用相同的文件(名称)并FileInputStream在将来读取数据.

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();
}
Run Code Online (Sandbox Code Playgroud)

  • 如果出现异常,则会发生泄漏系统资源. (2认同)

Jos*_*ter 30

简单的功能

试试这个简单的功能,将它整齐地包裹起来:

// 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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

感谢Jordan LaPrise和他的回答.


vov*_*ost 13

Kotlin版本(经过测试,无需库):

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()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我们利用use功能将在最后自动关闭两个流。

即使发生异常,也可以正确关闭流。

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/use.html
https://kotlinlang.org/docs/tutorials/kotlin-for-py/scoped-resource-usage.html


Tua*_*hau 7

更短的版本:

OutputStream out = new FileOutputStream(file);
fos.write(IOUtils.read(in));
out.close();
in.close();
Run Code Online (Sandbox Code Playgroud)

  • 因为它需要来自Apache commons的IOUtils,并且这是一个重量级依赖,无法添加到移动应用程序.大多数人宁愿选择依赖于标准SDK类的解决方案. (13认同)

vov*_*ost 5

这是一个解决所有异常的解决方案,它基于先前的答案:

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)