Stream流,properties、EnvironmentPostProcessor springboot多配置文件

 

 

@Controller @RequestMapping("/hello3") @ResponseBody 直接响应json格式

OutputStream 输出流,用来write写的,把数据写进入
如果是文件输出流,结果就是把数据写入文件
如果是HttpURLConnection输出流,结果就是把数据写入http发送数据

InputStream 输入流,用来read读取的,把数据读出来
如果是文件输入流,结果就是把数据从文件中读取到字节、字符数组中
如果是HttpURLConnection输入流,结果就是读取数据接收http数据

字符流(一次可以处理一个缓冲区)一次操作比字节流(一次一个字节)效率高。
字节流通常用于处理二进制数据,不支持直接读写字符;字符流通常用于处理文本数据
在读写文件需要对文本内容进行处理:按行处理、比较特定字符的时候一般会选择字符流;仅仅读写文件,不处理内容,一般选择字节流
https://ww.cnblogs.com/liangbaolong/p/12880487.html

   public static byte[] readFromFile(){
        String path = "test.txt";
        byte[] data = new byte[10];
        char[] chars = new char[10];
        try {
            FileInputStream fileInputStream = new FileInputStream(new File(path));
            InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
            Reader reader = new BufferedReader(inputStreamReader);

            FileOutputStream fileOutputStream = new FileOutputStream(new File("test2.txt"));
            int b = 0;
            while ((b = fileInputStream.read(data)) >=0){
                fileOutputStream.write(data,0,b);
                data = new byte[10];
            }
            fileOutputStream.flush();
            fileOutputStream.close();
            fileInputStream.close();
            FileWriter fw = new FileWriter(new File("test2.txt")); //文件输出流 (字符流)
            int b = 0;
            while ( (b = reader.read(chars)) >= 0) {
                System.out.println(b);
                fw.write(chars,0,b);//此写法可以防止最后一组数据填不满,把null数据也写到fw里
//                fw.write(chars);
                chars = new char[10];
            }
            fw.flush();
            reader.close();
            fw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return  null;
    }

  

从目标文件或资源读取
URL u = new URL(url);
UrlResource ur = new UrlResource(u);               
输入读:
InputStream in = ur.getInputStream(); //字节输入流 例如从url资源获取
FileInputStream in = new FileInputStream(new File("D:/test.txt")); 文件输入流(字节流)
FileReader fr = new FileReader(new File("D:/test.txt")); 文件输入流(字符流)
InputStreamReader isr = new InputStreamReader(in,"gbk"); 字符输入流
Reader read = new BufferedReader(isr);  字符输入流
输出写:
OutputStream outStream = response.getOutputStream(); 字节输出流  例如从http响应获取
ByteArrayOutputStream bao = new ByteArrayOutputStream(); 字节输出流
FileOutputStream fos = new FileOutputStream(file); 文件输出流 (字节流)
FileWriter fw = new FileWriter(new File("D:/test2.txt")); 文件输出流 (字符流)
OutputStreamWriter out = new OutputStreamWriter(fos); 字符输出流
Writer wr = new BufferedWriter(out); 字符输出流
字节流:
while((i=in.read(b))>=0){//从输入流读取到字节数组  i是返回的读到b的字节个数 返回-1表示已读完
   bao.write(b);//字节数组写入输出流
   b = new byte[1024];
}
字符流:
while((c= read.read(ch))>=0){ //从输入流读取字符数组
 //out.write(ch,0, c); //字符数组写入输出流
 wr.write(ch);
 ch = new char[5];
}
wr.flush();
wr.close();
 
操作字符流涉及字符编码,字节流不涉及
基于字节流的stream:
DataOutputStream----DataInputStream:
FileOutputStream-----FileInputStream:
基于字符流的stream(典型的以write和reader来标识的):
FileWriter---FileReader:
StringWriter---StringReader:
BufferedWriter--BufferedReader

 

@RequestMapping("/hello2")
    public void hello2(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        MultipartHttpServletRequest multipartRequest  =  (MultipartHttpServletRequest) request;
        MultipartFile multipartFile = multipartRequest.getFile("file");
        String imageNameOriginal  = multipartFile.getOriginalFilename();
        System.out.println("uploadCostomerImg imageNameOriginal:"+imageNameOriginal);

        String[] ss = imageNameOriginal.split("\\\\");
        File fileupload = new File("F:\\study-idea\\space\\xmhAID\\file\\"+ss[ss.length-1]);
        //读取图片
        multipartFile.transferTo(fileupload);//读取流到本地文件
        System.out.println("uploadCostomerImg 图片地址:"+ fileupload);
    }
## 是设置单个文件的大小
spring.http.multipart.maxFileSize=300Mb
是设置单次请求的文件的总大小
spring.http.multipart.maxRequestSize=300Mb
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<form action="http://192.168.206.1:9990/hello2" enctype="multipart/form-data" method="post">
 上传文件:<input type="file" name="file"><br/> 
<input type="submit" value="提交"> 
</form>

// 字节输出流,用于临时存储读取的字节(自动扩容)
ByteArrayOutputStream out = new ByteArrayOutputStream();

public static String getImageBase64StringByUrl(String imageUrl) {
        if (StringUtils.isEmpty(imageUrl)) {
            return "";
        }
        HttpURLConnection connection = null;
        // 字节输出流,用于临时存储读取的字节(自动扩容)
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            URL url = new URL(imageUrl);
            // 3. 打开 HTTP 连接(支持 HTTP 和 HTTPS)
            connection = (HttpURLConnection) url.openConnection();
            // 4. 设置请求方法(GET 方法获取图片)
            connection.setRequestMethod("GET");
            // 5. 设置超时时间(连接超时 + 读取超时)
            connection.setConnectTimeout(5000);
            connection.setReadTimeout(5000);
            // 6. 设置请求头(模拟浏览器请求,避免部分服务器拒绝)
            connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");
            // 7. 发送请求并获取响应码(200 表示成功)
            int responseCode = connection.getResponseCode();
            if (responseCode != HttpURLConnection.HTTP_OK) {
                throw new IOException("获取图片失败,响应码:" + responseCode);
            }
            InputStream is = connection.getInputStream();
            byte[] data = new byte[4096];
            int length;
            while ((length = is.read(data)) != -1) {
                out.write(data, 0, length);
            }
            out.flush();
            BASE64Encoder encoder = new BASE64Encoder();
            log.info("data**********************"+out.toByteArray().length);
            return encoder.encode(out.toByteArray());
        } catch (Exception e){
            log.error(e.getMessage(),e);
        }finally {
            connection.disconnect();
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

字节流转文件

            File file = new File("D:\\test.PNG");
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(out.toByteArray());
            fos.flush();
            fos.close();

  

 

  

动态添加properties

@Configuration
public class EnvironmentConfig {
    @Autowired
    private ConfigurableEnvironment environment;
    @PostConstruct
    public void addEnvironmentProperties() {
        Map<String, Object> map = new HashMap<>();
        map.put("my.custom.property", "myValuexx");
        MapPropertySource propertySource = new MapPropertySource("property", map);
        environment.getPropertySources().addFirst(propertySource);
    }
}
//只能从environment中获取 ApplicationContextHolder自定义类,获取上下文
Environment environment = ApplicationContextHolder.getContext().getEnvironment();
String es = environment.getProperty("my.custom.property");

总结:yaml与properties互通,ymal覆盖properties

1、yaml中的配置可以在TestProperties实例中获取,会覆盖properties配置
@ConfigurationProperties(prefix = "my.custom")
@PropertySource(value = "customProperties.properties")
public class TestProperties {
2、可以通过$方式获取properties中的值,yaml值会覆盖properties配置
@Value("${my.custom.machine:s}")
private String testXmh;

 

 

1,src\main\resources\META-INF\spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\other.impl.MyInterfaceImpl
2,
@Configuration
@Import(MyInterfaceImpl.class)
把测试类放到外层,不能被springboot扫描到other.IMyInterface
二者同等效果,把非本项目的类,实例化到上下文中

多环境单配置文件

@Value("${testx}")
private String testx;

application.properties
spring.profiles.active=@spring.profiles.active@
application-dev.properties
testx=testxmhdev
application-test.properties
testx=testxmhtest


 <profiles>
    <profile>
        <id>dev</id>
        <properties>
            <env>dev</env>
            <spring.profiles.active>dev</spring.profiles.active>
        </properties>
    </profile>
    <profile>
            <id>test</id>
            <properties>
                <env>test</env>
                <spring.profiles.active>test</spring.profiles.active>
            </properties>
    </profile>
    </profiles>




多环境多配置文件

src/main/resources/META-INF/spring.factories
org.springframework.boot.env.EnvironmentPostProcessor=\cn.com.config.Configs

src/main/resources/config/dev/configTest1.properties
src/main/resources/config/dev/configTest2.properties
src/main/resources/config/test/configTest1.properties
src/main/resources/config/test/configTest2.properties
//@Configuration
public class Configs implements EnvironmentPostProcessor, Ordered {
//    private Logger logger = LoggerFactory.getLogger(Configs.class);

    @Override
    @SuppressWarnings({"unchecked", "rawtypes"})
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        System.out.println("postProcessEnvironment******profiles:"+environment.getActiveProfiles());

        //忽略不可解析的 `${xxx}`
        environment.setIgnoreUnresolvableNestedPlaceholders(true);

        MutablePropertySources propertySources = environment.getPropertySources();
        Properties props = getConfig(environment);
        propertySources.addLast(new PropertiesPropertySource("xmh", props));//thirdEnv      
        for (PropertySource<?> propertySource : propertySources) {
            if (propertySource.getSource() instanceof Map) {
                Map map = (Map)propertySource.getSource();
                for (Object key : map.keySet()) {
                    String keyStr = key.toString();
                    Object value = environment.getProperty(keyStr);
//                    if ("druid.password,druid.writer.password,druid.reader.password".contains(keyStr)) {
//                        String dkey = (String)map.get("druid.key");
//                        dkey = DataUtil.isEmpty(dkey) ? Constants.DB_KEY : dkey;
//                        value = SecurityUtil.decryptDes(value.toString(), dkey.getBytes());
//                        map.put(key, value);
//                    }
//                    PropertiesUtil.getProperties().put(keyStr, value.toString());
                }
            }
        }

    }

    @Override
    public int getOrder() {
        return ConfigFileApplicationListener.DEFAULT_ORDER + 1;
    }
    // 加载配置文件
    private Properties getConfig(ConfigurableEnvironment environment) {
        String[] profiles = environment.getActiveProfiles();

        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        List<Resource> resouceList = new ArrayList<>();

        loadResource(resolver,resouceList,profiles,"classpath*:config");

        try {
            PropertiesFactoryBean config = new PropertiesFactoryBean();
            config.setLocations(resouceList.toArray(new Resource[]{}));
            config.afterPropertiesSet();
            return config.getObject();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private void loadResource(PathMatchingResourcePatternResolver resolver, List<Resource> resouceList, String[] profiles, String configPath) {
        addResources(resolver, resouceList, configPath+"/*.properties");
        for (String p : profiles) {
            if (p != null || "".equals(p)) {
                p = p + "/";
            }
            addResources(resolver, resouceList, configPath+"/" + p + "*.properties");
        }
    }
    private void addResources(PathMatchingResourcePatternResolver resolver, List<Resource> resouceList, String path) {
        try {
            Resource[] resources = resolver.getResources(path);
            for (Resource resource : resources) {
                resouceList.add(resource);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

  

 

posted @ 2022-07-06 16:41  XUMT111  阅读(81)  评论(0)    收藏  举报