Java怎么将一个InputStream转换成为String?
一个流变成一个String对象,我们首先要去了解的就是他们有什么共同点,表面上看他们一个对象,一个流,完全就没法转换,不过通过一些分解,然后在转换是完全可以做到的。
在转换之前我们不妨了解一下流,到底是什么?
在 Java 中所有数据都是使用流读写的。流是一组有序的数据序列,将数据从一个地方带到另一个地方。根据数据流向的不同,可以分为输入(Input)流和输出(Output)流两种。InputStream就是输入,OutputStream就是输出流
输入流InputStream
在java中InputStream是字节输入流,用来将文件中的数据读取到java程序中。InputStream是所有字节输入流的顶层父类,是一个抽象类。如果要用,需要使用子类。比如我们创建一个InputStream的时候,我们继续按照这么创建
InputStream inputStream = new FileInputStream("E:\\codework\\demo1\\demo\\src\\main\\java\\com\\echo\\demo\\DemoApplication.java");
从介绍中我们可以看到InputStream就是字节输入流,我们可以去看看它相关的API,在电脑中,不管是文件也好还是视频也好,最底层都是字节,String是一个对象,底层存储也是字节的形式。所以这里我们就找到了他们可以转换的点了。
怎么使用InputStream读取文件内容
既然我们的文件底层是字节存储的,那我们了解一下InputStream读取API看看它是怎么读取字节的
名称 | 作用 |
int read() | 从输入流读入一个 8 字节的数据,将它转换成一个 0~ 255 的整数,返回一个整数,如果遇到输入流的结尾返回 -1 |
int read(byte[] b) | 从输入流读取若干字节的数据保存到参数 b 指定的字节数组中,返回的字节数表示读取的字节数,如果遇到输入流的结尾返回 -1 |
int read(byte[] b,int off,int len) | 从输入流读取若干字节的数据保存到参数 b 指定的字节数组中,其中 off 是指在数组中开始保存数据位置的起始下标,len 是指读取字节的位数。返回的是实际读取的字节数,如果遇到输入流的结尾则返回 -1 |
//调用read方法读取数据
StringBuffer sb = new StringBuffer();
int i;
while ((i = inputStream.read()) != -1) {
// inputStream.read()) 读取文件的一个字节(8个二进制位),并将其由二进制转成十进制的整数返回
// 转成字符
char c = (char) i;
sb.append(c);
}
System.out.println(sb.toString());
注意: 这种方式不能读取中文,一个中文占多个字节,此时一次读取一个字节会把中文拆开读。
解决不能读取中文的问题
我们可以从API中看到inputStream可以直接从流里面获取到一个字节数组,那么这就解决了我们的中文占多个字节的问题
StringBuffer sb = new StringBuffer();
byte arr[] = new byte[3];
int i;
while ((i = inputStream.read(arr)) != -1) {
// 转成字符
String s = new String(arr);
sb.append(s);
}
System.out.println(sb.toString());
不同的编码格式占字节数是不同的,UTF-8编码下一个中文所占字节也是不确定的,可能是2个、3个、4个字节;所以我们要根据实际情况去设置字节数组的长度,解决了这个问题我们的读取就没问题ile
封装好的方法
StringWriter stringWriter = new StringWriter();
IOUtils.copy(inputStream, stringWriter);
String s = stringWriter.toString();
System.out.println(s);
封装好的方法都有可能需要引入相应的依赖,对应的方法很多,记得引入依赖就好了