Java-Stream流,异常捕获

本文介绍 Java 中 Stream API 的使用方法,包括如何从集合、数组等创建 Stream 流,演示了 Stream API 的常见操作如过滤、映射、排序等,并展示了如何将处理后的数据收集到不同的集合中。

Stream流

获取流

public class Streamdemo {
    public static void main(String[] args) {
        //所有集合都可以直接创建流
        List<String> names = new ArrayList<>();
        Set<String> nameset = new HashSet<>();
        Stream<String> name =names.stream();
        Stream<String> nameset1 =nameset.stream();
        System.out.println(name);

        //map创建流
        Map<String,Integer> maps = new HashMap<>();
        // 键流
        Stream<String> mapString = maps.keySet().stream();
        // 值流
        Stream<Integer> mapValue= maps.values().stream();
        // 键值对流
        Stream<Map.Entry<String, Integer>> keyandvalue =  maps.entrySet().stream();


        //数组流
        String[] strlist = {"a","b","c"};
        Stream<String> str1 = Stream.of(strlist);
        Stream<String> str2 = Arrays.stream(strlist);
        
    }
}

 常用api


import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;

public class Streamdeom2 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        List<String> list1 = new ArrayList<>();
        Collections.addAll(list,"张*","张**","张***","张****");
        Collections.addAll(list1,"王*","王**","王***","王****");
//        list.stream().findFirst()
        list.stream().limit(3).forEach(s->System.out.println(s)); //前三位
        list.stream().skip(3).forEach(s->System.out.println(s)); //跳过前三位
        list.stream().filter(s -> s.startsWith("张")).forEach(s->System.out.println(s)); //过滤
        list.stream().distinct().forEach(s->System.out.println(s)); // 去重
        list.stream().map(s -> "加工后" + s).forEach(s -> System.out.println(s));  //加工方法
        list.stream().map(s -> new Student(s)).forEach(s -> System.out.println(s)); //加工到某个对象
        list.stream().map(Student::new).forEach(System.out::println); //与上一行一致,构造器引用
        Stream<String> newlist = list.stream();
        Stream<String> newlis1 = list1.stream();
        Stream.concat(newlist,newlis1).forEach(s -> System.out.println(s));  //合并流
        list.stream().sorted((e1,e2)->Double.compare(e1.getMoney() , e2.getMoney()))  //排序
        list.stream().max((e1,e2)->Double.compare(e1.getMoney() , e2.getMoney())) //取最大值

}
}
class Student{
    private String name;

    public Student(){};

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                '}';
    }

    public Student(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

收集成数组或集合


public class tolistdemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        Collections.addAll(list,"王*","王**","王***","王****");
        Stream<String>  newstream = list.stream().filter(s -> s.startsWith("王"));
        List<String> list2 = newstream.collect(Collectors.toList()); //转成可变list
        list2.add("java");
        System.out.println(list2);
//        List<String> list2 = newstream.tolist() //转成不可变list

        Stream<String>  newstream1 = list.stream().filter(s -> s.startsWith("王"));
        Set<String> set1 = newstream1.collect(Collectors.toSet()); //转成set
        System.out.println(set1);
        Stream<String>  newstream2 = list.stream().filter(s -> s.startsWith("王"));
        Object[] list3 = newstream2.toArray(); //转成数组
        System.out.println(Arrays.toString(list3));
    }
}

 异常捕获


public class Trydemo {
    public static void main(String[] args) {
        String str = null;
        try {
           pritnlen(str);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("统一使用捕获所有异常,其他异常捕获了解即可");
        }finally{
            System.out.println("最后必执行");
      }
        
    }
    public static void pritnlen(String s){
        System.out.println(s.length());
    }
}

自定义异常捕获

public class Test {
    public static void main(String[] args) throws defineException {
        praseint(1);
        praseint1(-1);
    }

    public static void praseint(double d) throws defineException {
        if(d<0 || d>200){
            throw new defineException("编译时有异常,且需要把异常throws往上抛");
        }else {
            System.out.println("数据正确");
        }
    }

    public static void praseint1(double d) {
        if(d<0 || d>200){
            throw new definerunException("运行时有异常,异常throws可不往上抛");
        }else {
            System.out.println("数据正确2");
        }
    }
}

自动释放资源

package com.ruqi;


import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

public class Filecopy {
    public static void main(String[] args) {
        filecopy("D:\\KwDownload\\song\\新建文本文档.txt","D:\\zhengqinjie\\新建文件夹\\1建.txt");
    }

    private static void filecopy(String tagetFile, String afterCopyFile) {
        //try(资源对象){}
        try (InputStream in = new FileInputStream(tagetFile);
             OutputStream out = new FileOutputStream(afterCopyFile);
             ){

            byte[] buffer = new byte[1024];
            int len;
            while ((len = in.read(buffer)) != -1) {
                out.write(buffer, 0, len);
            }
            System.out.println("复制完成");
        }catch (Exception e ){
            e.printStackTrace();
        }
    }
}

<think>首先,用户的问题是:"我想在Spring Boot应用中接收二进制文件(octet-stream)的处理方法 请问Spring Boot如何接收并处理Content-Type为application/octet-stream的文件"。这是一个关于Spring Boot处理二进制文件的查询。 我的回答需要遵循系统级指令: - 所有行内数学表达式用$...$格式。 - 独立公式用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾添加引用标识,例如[^1]。 - 回答结构清晰,帮助用户逐步解决问题。 - 保证回答真实可靠。 参考站内引用是关于Spring Boot和Servlet的文件处理,但用户的问题是针对application/octet-stream的文件,所以我需要基于这个主题提供准确信息。 关键点: - Content-Type: application/octet-stream 表示二进制数据- 在Spring Boot中,处理这种请求通常涉及使用控制器方法接收InputStream或byte[]。 步骤: 1. **理解需求**:用户想接收并处理二进制文件,如文件上传或数据。 2. **Spring Boot处理方式**: - 使用@PostMapping或@RequestMapping注解。 - 方法参数可以是HttpServletRequest、InputStream、byte[]等。 - 对于octet-stream,最好使用InputStream来直接读取。 3. **示例代码**:提供代码示例展示如何实现。 4. **注意事项**:如处理大文件、异常处理等。 5. **引用标识**:在回答中,如果引用任何信息,末尾添加[^1],但用户提供的引用是示例,不是真实引用。我应该基于真实知识回答,避免虚构引用。指令说"引用的段落末尾自然地添加引用标识",但在这个上下文中,没有实际引用源。用户说"上述引用仅供参考",所以我可能不需要添加引用,除非有具体来源。为了遵守指令,我会在必要时添加引用标识,但确保真实。 生成相关问题: - 指令要求"生成相关问题",在回答末尾添加相关问题部分。 回答结构: - 介绍:简要解释如何处理。 - 步骤:分步说明。 - 代码示例:提供Spring Boot控制器示例。 - 注意事项:讨论性能、错误处理。 - 相关问题:生成2-3个相关问题。 内容大纲: 1. **介绍**:解释application/octet-stream是什么,为什么需要特殊处理。 2. **处理方法**: - 使用@PostMapping接收请求。 - 参数类型:HttpServletRequest、InputStream、byte[]。 - 推荐使用InputStream避免内存溢出。 3. **代码示例**:展示一个简单的控制器方法。 4. **优化和注意事项**:如使用缓冲区、处理大文件、异常处理。 5. **相关问题**:生成相关问题。 生成相关问题: - 基于主题,如: 1. 如何处理大文件以避免内存溢出? 2. Spring Boot中如何验证octet-stream请求? 3. 如何将接收的二进制保存为文件? 确保中文回答。 最终输出格式: - 回答主体。 - 末尾添加"§§相关问题§§"部分。</think>### Spring Boot接收并处理Content-Type为application/octet-stream的文件 在Spring Boot应用中,处理Content-Type为`application/octet-stream`的二进制文件(如文件上传或数据)时,需要直接操作输入来避免内存溢出,并高效处理数据。以下我将逐步解释实现方法,包括代码示例和注意事项。整个过程基于Spring MVC框架,并利用Servlet的底层支持[^1]。 #### 步骤1: 理解application/octet-stream - `application/octet-stream`表示原始的二进制数据,常用于文件传输(如APK文件、图像或任意二进制数据)。 - 在Spring Boot中,处理这种请求时,不能使用`MultipartFile`(它适用于`multipart/form-data`类型),而应使用`InputStream`或`byte[]`直接读取数据- 关键优势:直接式处理,减少内存占用,尤其适合大文件。 #### 步骤2: 创建控制器方法 使用`@PostMapping`注解定义端点,方法参数选择`InputStream`或`HttpServletRequest`来获取原始。以下是推荐做法: - **使用`InputStream`参数**:这是最安全的方式,Spring Boot会自动注入请求输入- **添加`@RequestBody`注解**:明确指示Spring将整个请求体作为二进制处理。 - **处理程**:读取 → 处理数据(如保存到文件或解析)→ 返回响应。 示例代码(使用Spring Boot控制器): ```java import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; @RestController public class FileStreamController { @PostMapping(value = "/upload/octet-stream", consumes = "application/octet-stream") public ResponseEntity<String> handleOctetStream(@RequestBody InputStream inputStream) { try { // 示例:将保存到本地文件(实际中可替换为其他处理逻辑) Path filePath = Paths.get("uploaded_file.bin"); Files.copy(inputStream, filePath, StandardCopyOption.REPLACE_EXISTING); // 返回成功响应 return ResponseEntity.ok("文件接收并保存成功"); } catch (Exception e) { // 异常处理 return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body("处理失败: " + e.getMessage()); } finally { // 确保关闭 try { if (inputStream != null) { inputStream.close(); } } catch (Exception e) { // 忽略关闭异常 } } } } ``` #### 步骤3: 注意事项和优化 - **大文件处理**:使用`InputStream`而不是`byte[]`,避免将整个文件加载到内存。对于超大文件(如GB级),结合`BufferedInputStream`提高读取效率。 - 示例优化代码: ```java try (BufferedInputStream bufferedStream = new BufferedInputStream(inputStream)) { byte[] buffer = new byte[8192]; // 8KB缓冲区 int bytesRead; while ((bytesRead = bufferedStream.read(buffer)) != -1) { // 处理每个缓冲区块(如写入文件或数据库) } } ``` - **错误处理**:添加全局异常处理器(如`@ControllerAdvice`)捕获`IOException`,防止应用崩溃。 - **性能考虑**:Spring Boot底层依赖Servlet的`HttpServletRequest`,对于高并发场景,使用异步处理(如`DeferredResult`)或增加服务器内存限制[^1]。 - **安全验证**:在方法中添加参数验证,例如检查请求头`Content-Length`或使用`@RequestHeader`验证来源。 - **测试方法**:使用工具如Postman或cURL发送octet-stream请求: ```bash curl -X POST http://localhost:8080/upload/octet-stream \ -H "Content-Type: application/octet-stream" \ --data-binary "@path/to/yourfile.bin" ``` #### 总结 通过上述方法,Spring Boot能高效接收和处理二进制文件。核心是直接操作`InputStream`,实现式读取,避免内存问题。底层原理上,Spring Boot封装了Servlet的`HttpServletRequest`,简化了开发,但需注意资源管理[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郑*杰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值