探索InputStream 和 OutputStream 家族成员的心得<一>

本文深入探讨了Java程序中的流操作,包括输入、输出的概念,重点介绍了文件字节流类(FileInputStream、FileOutputStream)的使用方法,并详细解释了缓冲流(BufferedOutputStream、BufferedInputStream)如何提高读写效率。此外,文章还展示了如何利用字符转换流(InputStreamReader, OutputStreamWriter)进行字符集转换,确保数据正确传输。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

探索InputStream 和 OutputStream 家族成员的心得
java程序中的流操作主要解决的是,程序与外界的数据交互问题,也就是说这个知识也是必须要掌握的。

问题:什么是输入?什么是输出?
这个也是一个重要知识,因为在懂得这个概念才能明白数据的传输方向,才能很肯定地使用相关的类进行操作。
输入:从外界环境,将数据传送给运行程序的内存,在内存看来,是读       取数据。
输出:从内存方向,将数据传送给外界环境(比如一个文件),在内存       看来,是向外写数据。
一、文件的字节流类
FileOutputStream 、FileInputStream
import java.io.FileInputStream;

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

/**
 * 操作:文件的字节流相关操作
 * 
 * @author Character_Painter
 *
 */
public class StreamDemo {
	public static void main(String[] args) throws IOException {
		/*
		 * 向文件中写数据
		 */
		FileOutputStream fos = new FileOutputStream("demo.txt",true);
		//创建文件字节输出流-----目的地demo.txt,参数为true是代表追加模式
		byte [] b ="java".getBytes();//将字符串的字节长度存在字节数据中
		
		fos.write(11);//将11通过文件字节输出流写到文件中
		
		fos.write(b, 0, b.length);
		/*
		 * 由于在这种情况下,写数据成功后,--打开demo.txt会是乱码-----原因:编码集不一样
		 */
		
		FileInputStream fis  = new FileInputStream("demo.txt");
		System.out.println(fis.read());//read的返回值是int型
		
		System.out.println(fis.read(b));//将字节数据的长度读出来---显示出来
		/*
		 * 从文件中读取数据
		 * 
		 * 最终在Console中显示为11,4
		 */
		fos.close();
                fis.close();
	}

}
总结:文件的字节流主要针对的是对文件的操作,读写文件
拓展:利用文件的字节流拷贝文件
/**
 * 操作:利用文件的字节流--进行文件的拷贝操作
 * @author Character_Painter
 *
 */
public class Copydemo {

	public static void main(String[] args) throws IOException {
		
		/*
		 * 拷贝文件操作
		 */
		FileInputStream fis = new FileInputStream("demo.txt");//文件字节输入流
		FileOutputStream fos = new FileOutputStream("demo_copy.txt");//文件字节输出流
		int b =-1;
		while((b=fis.read())!=-1){
			/*
			 * 读取源文件的字节数据,如不为-1,就把当前读到的字节数据写到拷贝文件中
			 */
			fos.write(b);
		}

		fis.close();
                fos.close();
	}

}

 
二、缓冲流
BufferedOutputStream 、BufferedInputStream

缓冲流的作用:一次性写出若干字节数据,减少写出的次数,来提高读写效率。
利用缓冲流拷贝文件
/**
 * 操作:利用缓冲字节流--进行文件的拷贝操作
 * @author Character_Painter
 *
 */
public class Copydemo {

	public static void main(String[] args) throws IOException {
		
		/*
		 * 拷贝文件操作
		 */
		FileInputStream fis = new FileInputStream("demo.txt");//文件字节输入流
		BufferedInputStream bis = new BufferedInputStream(fis);//缓冲字节输入流
		FileOutputStream fos = new FileOutputStream("Buffer_demo_copy.txt");//文件字节输出流
		BufferedOutputStream bos = new BufferedOutputStream(fos);//缓冲字节输出流
		int b =-1;
		while((b=bis.read())!=-1){
			/*
			 * 读取源文件的字节数据,如不为-1,就把当前读到的字节数据写到拷贝文件中
			 */
			bos.write(b);
		}
		bos.close();
		bis.close();
		
	}

}
三、字符转换流
将字节流转换成字节流,InputStreamReader,OutputStreamWriter
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

/**
 * 操作:使用字符转换流--设定特定的字符集,读写到文件中
 * 
 */
public class chars {
	public static void main(String[] args) throws IOException {
		/*
		 * 利用转换流在文件中写出字符串
		 */
		FileOutputStream fos = new FileOutputStream("change.txt");
		OutputStreamWriter osw = new OutputStreamWriter(fos,"GBK");
		String str ="学习字符转换流";
		osw.write(str);
		osw.close();
		
		/*
		 * 利用转换流读出文件中字符串
		 */
		FileInputStream fis = new FileInputStream("change.txt");
		InputStreamReader isr = new InputStreamReader(fis,"GBK");
		int c =-1;
		while((c=isr.read())!=-1){
			System.out.println((char)c);
		}
	        isr.close();
         }

}


















<think>好的,我现在需要解决用户的问题:如何将InputStream转换为ResponseEntity<StreamingResponseBody>,在Java SpringBoot中实现。首先,我得回忆下SpringBoot处理式响应的相关知识。用户提到InputStream需要转换成StreamingResponseBody,这说明他们可能是在处理大文件或式数据,想要高效地传输数据,避免内存溢出。Spring Boot的StreamingResponseBody适合这种场景,因为它允许以非阻塞的方式写入响应体。接下来,我需要考虑如何将InputStream的数据读取到StreamingResponseBody中。通常的做法是使用个输出,将输入的数据写入输出。这里需要注意异常处理资源关闭,确保被正确释放,避免资源泄漏。然后,构建ResponseEntity对象时需要设置正确的HTTP状态码响应头,特别是Content-TypeContent-Length(如果已知的话)。但如果是式传输,可能Content-Length无法提前确定,这时候需要确保服务器客户端支持分块传输编码(chunkedtransferencoding)。可能的问题点包括:的正确关闭、异常处理、响应头的设置。例如,如果在写入过程中发生IOException,应该如何处理?需要捕获异常并记录,同时可能关闭。另外,是否需要使用缓冲来提高传输效率?可以适当引入缓冲区,减少IO操作次数。 代码结构大致如下:创建个StreamingResponseBody的匿名类,实现其writeTo方法,在该方法中使用输入读取数据,并写入输出。然后,将StreamingResponseBody包装到ResponseEntity中,设置相应的响应头。还需要注意,InputStream的来源是否可靠,比如是否是文件输入或者其他资源,需要确保在使用完毕后正确关闭。但在这个场景中,StreamingResponseBody的writeTo方法执行完毕后,框架应该会处理的关闭,不过为了安全起见,最好在finally块中关闭输入。测试时需要考虑大文件的情况,确保内存占用不会过高,以及传输过程中没有中断。此外,可能需要设置超时时间,防止长时间占用连接。用户可能还想知道如何设置响应头,比如Content-Disposition来指定文件名,或者处理范围请求(Range requests),但这可能超出当前问题的范围。不过,根据用户的具体需求,可能需要进步的调整。 总结步骤:1.创建StreamingResponseBody,在其writeTo方法中读取InputStream并写入输出。2.处理异常,确保被正确关闭。3.构建ResponseEntity,设置状态码必要的响应头。</think>在Spring Boot中将`InputStream`转换为`ResponseEntity<StreamingResponseBody>`可通过式传输实现高效数据返回,适用于大文件下载或实时数据场景。以下是实现步骤: --- ### **实现代码** ```java import org.springframework.http.ResponseEntity; import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; import java.io.InputStream; import java.io.OutputStream; public ResponseEntity<StreamingResponseBody> convertToStreamingResponse(InputStream inputStream) { StreamingResponseBody responseBody = outputStream -> { try (inputStream) { // 自动关闭InputStream byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); outputStream.flush(); } } catch (IOException e) { // 处理异常(如记录日志) throw new RuntimeException("传输失败", e); } }; return ResponseEntity.ok() .header("Content-Type", "application/octet-stream") // 根据实际类型调整 .body(responseBody); } ``` --- ### **关键点说明** 1. **式传输机制** `StreamingResponseBody`通过非阻塞方式逐块写入响应体,避免次性加载全部数据到内存[^1]。 2. **资源管理** 使用`try-with-resources`确保`InputStream`在使用后自动关闭,防止资源泄漏。 3. **异常处理** 捕获`IOException`并重新抛出,确保传输中断时客户端能收到错误响应。 4. **响应头配置** - 设置`Content-Type`(如文件下载用`application/octet-stream`)。 - 可选添加`Content-Disposition`指定文件名: `.header("Content-Disposition", "attachment; filename=\"file.txt\"")` --- ### **性能优化建议** - 调整`buffer`大小(如`4096`字节)以平衡IO效率与内存占用。 - 分块传输时,若内容长度已知,可添加`.header("Content-Length", String.valueOf(fileSize))`。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值