有人能解释一下什么是输入流和输出流吗?

我对InputStream和OutputStream的用例感到困惑。

如果你能在解释的同时附上一段代码,那就太好了。谢谢!


你从一个输入流中读取并写入输出流。

例如,假设您想复制一个文件。您将创建一个FileInputStream来从源文件读取,创建一个FileOutputStream来写入新文件。

如果您的数据是字符流,您可以使用FileReader而不是InputStream,如果您愿意,可以使用FileWriter而不是OutputStream。

InputStream input = ... // many different types
OutputStream output = ... // many different types

byte[] buffer = new byte[1024];
int n = 0;
while ((n = input.read(buffer)) != -1)
    output.write(buffer, 0, n);

input.close();
output.close();

OutputStream是表示写入输出的抽象类。有许多不同的OutputStream类,它们写入特定的东西(如屏幕、文件、字节数组或网络连接等)。InputStream类访问相同的东西,但是它们从中读取数据。

下面是一个很好的基本示例,使用FileOutputStream和FileInputStream将数据写入文件,然后再将其读入。


InputStream和OutputStream的目标是抽象输入和输出的不同方式:流是文件、网页还是屏幕都不重要。重要的是您从流中接收信息(或将信息发送到流中)。

InputStream用于读取的许多内容。

OutputStream用于很多你写入的东西。

下面是一些示例代码。它假设InputStream instr和OutputStream osstr已经创建:

int i;

while ((i = instr.read()) != -1) {
    osstr.write(i);
}

instr.close();
osstr.close();

InputStream用于读取,OutputStream用于写入。它们作为装饰器彼此连接,以便您可以从所有不同类型的源读取/写入所有不同类型的数据。

例如,你可以把原始数据写入一个文件:

File file = new File("C:/text.bin");
file.createNewFile();
DataOutputStream stream = new DataOutputStream(new FileOutputStream(file));
stream.writeBoolean(true);
stream.writeInt(1234);
stream.close();

阅读书面内容:

File file = new File("C:/text.bin");
DataInputStream stream = new DataInputStream(new FileInputStream(file));
boolean isTrue = stream.readBoolean();
int value = stream.readInt();
stream.close();
System.out.printlin(isTrue + " " + value);

您可以使用其他类型的流来增强读/写。例如,为了提高效率,你可以引入一个缓冲区:

DataInputStream stream = new DataInputStream(
    new BufferedInputStream(new FileInputStream(file)));

您可以写入其他数据,如对象:

MyClass myObject = new MyClass(); // MyClass have to implement Serializable
ObjectOutputStream stream = new ObjectOutputStream(
    new FileOutputStream("C:/text.obj"));
stream.writeObject(myObject);
stream.close();

你可以从其他不同的输入源读取:

byte[] test = new byte[] {0, 0, 1, 0, 0, 0, 1, 1, 8, 9};
DataInputStream stream = new DataInputStream(new ByteArrayInputStream(test));
int value0 = stream.readInt();
int value1 = stream.readInt();
byte value2 = stream.readByte();
byte value3 = stream.readByte();
stream.close();
System.out.println(value0 + " " + value1 + " " + value2 + " " + value3);

对于大多数输入流,也有一个输出流。你可以定义自己的流来读取/写入特殊的东西,也有复杂的流来读取复杂的东西(例如,有用于读取/写入ZIP格式的流)。


来自Java教程:

流是数据序列。

程序使用输入流从源读取数据,一次一项:

程序使用输出流将数据写入目标,每次一项:

上图中的数据源和数据目的地可以是保存、生成或使用数据的任何东西。显然,这包括磁盘文件,但源或目标也可以是另一个程序、外围设备、网络套接字或数组。

oracle教程中的示例代码:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyBytes {
    public static void main(String[] args) throws IOException {

        FileInputStream in = null;
        FileOutputStream out = null;

        try {
            in = new FileInputStream("xanadu.txt");
            out = new FileOutputStream("outagain.txt");
            int c;

            while ((c = in.read()) != -1) {
                out.write(c);
            }
        } finally {
            if (in != null) {
                in.close();
            }
            if (out != null) {
                out.close();
            }
        }
    }
}

这个程序使用字节流将xanadu.txt文件复制到outagain.txt,每次写入一个字节

看看这个SE问题,了解更多关于高级字符流的细节,它是字节流上的包装器:

字节流和字符流


输出流通常与一些数据目的地相关,如文件或网络等。在java中,输出流是数据最终写入和结束的目的地

import java.io.printstream;

class PPrint {
    static PPrintStream oout = new PPrintStream();
}

class PPrintStream {
    void print(String str) { 
        System.out.println(str)
    }
}

class outputstreamDemo {
    public static void main(String args[]) {
        System.out.println("hello world");
        System.out.prinln("this is output stream demo");
    }
}

流:在外行术语中,流是数据,大多数通用流是数据的二进制表示。

输入流:如果您从文件或任何其他源读取数据,则使用的流是输入流。简单地说,输入流充当读取数据的通道。

输出流:如果你想从一个源(文件等)读取和处理数据,你首先需要保存数据,存储数据的意思是输出流。


流是液体、空气或气体的连续流动。

Java流是从源到目的的数据流。源或目标可以是磁盘、内存、套接字或其他程序。数据可以是字节、字符或对象。这同样适用于c#或c++流。爪哇溪流的一个很好的比喻是水从水龙头流入浴缸,然后流入排水沟。

数据表示流的静态部分;读和写方法是流的动态部分。

InputStream表示来自源的数据流,OutputStream表示进入目的地的数据流。 最后,InputStream和OutputStream是对数据(如C文件指针)的低级访问的抽象。


对于一种InputStream,您可以将其视为数据源的“表示”,就像文件一样。 例如:

FileInputStream fileInputStream = new FileInputStream("/path/to/file/abc.txt");

fileInputStream表示该路径中的数据,您可以使用read方法从文件中读取字节。

对于另一种类型的InputStream,它们接收另一种InputStream并进行进一步的处理,如解压。 例如:

GZIPInputStream gzipInputStream = new GZIPInputStream(fileInputStream);

gzipInputStream将fileInputStream视为压缩的数据源。当您使用read(buffer, 0, buffer.length)方法时,它将把gzip文件的一部分解压缩到您提供的缓冲区中。

我们使用InputStream的原因是,随着源文件中的数据越来越大,比如源文件中有500GB的数据,我们不想把所有东西都存储在内存中(昂贵的机器;对GC分配不友好),并且我们希望更快地获得一些结果(读取整个文件可能需要很长时间)。

对于OutputStream也是一样。我们可以开始移动一些结果到目的地,而不需要等待整个事情完成,加上更少的内存消耗。

如果你想要更多的解释和例子,你可以检查这些摘要:InputStream, OutputStream,如何使用InputStream,如何使用OutputStream


在继续其他伟大的答案时,用我简单的话来说:

流-像提到的@Sher Mohammad是数据。

输入流—例如是从文件中获取输入—数据。这种情况是当我有一个文件(用户上传一个文件-输入)-我想读取我们在那里有什么。

输出流-反之亦然。例如,您正在生成一个excel文件,并将其输出到某个地方。

“如何写入”文件,是在发送方(excel工作簿类)定义的,而不是在文件输出流。

请看这个例子。

try (OutputStream fileOut = new FileOutputStream("xssf-align.xlsx")) {
    wb.write(fileOut);
}
wb.close();