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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10854211/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:14:25  来源:igfitidea点击:

Android - Store inputstream in file

androidinputstream

提问by Dobes

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.

我正在从 url 检索 XML 提要,然后对其进行解析。我需要做的也是将其存储在手机内部,以便当没有互联网连接时,它可以解析保存的选项而不是实时选项。

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 对象,使用 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();

Any ideas how I can go about saving the input stream so I can load it later.

任何关于如何保存输入流以便稍后加载的想法。

Cheers

干杯

回答by Volodymyr Lykhonis

Here it is, input is your inputStream. Then use same File (name) and FileInputStreamto read the data in future.

在这里,输入是您的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();
}

回答by Joshua Pinter

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.

感谢 Jordan LaPrise 和他的回答

回答by vovahost

Kotlinversion (tested and no library needed):

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()
        }
    }
}

We take advantage of usefunction which will automatically close both streams at the end.

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

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

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

回答by Tuan Chau

A shorter version:

一个较短的版本:

OutputStream out = new FileOutputStream(file);
fos.write(IOUtils.read(in));
out.close();
in.close();

回答by vovahost

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();
        }
    }
}

回答by ccpizza

  1. In your application's build.gradlefile add under dependencies:
  1. 在您的应用程序build.gradle文件中添加dependencies
    implementation 'commons-io:commons-io:2.5'
  1. In your code:
  1. 在您的代码中:
// given you have a stream, e.g.
InputStream inputStream = getContext().getContentResolver().openInputStream(uri);

// you can now write it to a file with
FileUtils.copyToFile(inputStream, new File("myfile.txt"));

回答by android developer

There's the way of IOUtils:

有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;
}