V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
w11ya
V2EX  ›  问与答

萌新求教 Java 转码问题

  •  
  •   w11ya · 2023-01-05 11:09:57 +08:00 · 1333 次点击
    这是一个创建于 724 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在有一个导出文本文件后,文本文件能用 GBK 编码打开的需求,但是原来的代码是这样的

    InputStream inputStream = minioUtil.getObject(minioConfig.getBucketName(), fileVersion.getFsId());
    

    然后设置响应体的文件类型和响应头

    response.setContentType(contentType);
    response.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
    response.setHeader("Content-Length", "" + length);
    response.setHeader("fileName", "" + fileName);
    

    然后通过这个工具类去把 inputstream 流到 outputstream

    IOUtils.copy(inputStream, outputStream);
    

    我的想法一开始是用

    Reader r = new InputStreamReader(inputStream,"utf-8");
    BufferedReader br = new BufferedReader(r);
    Writer w = new OutputStreamWriter(outputStream,"GBK");
    BufferedWriter bw = new BufferedWriter(w);
    String s = null;
    while((s= br.readLine())!=null){
       bw.write(s);
    }
    br.close();
    bw.close();
    

    发现导出不了,发送的请求是 pending ,然后过了两分钟响应 200 ,弹不出文件保存框。 然后尝试用这个

    byte[] buffer = new byte[8192];
    int n;
    byte[] dest = new byte[8192];
    while(-1 != (n = inputStream.read(buffer))) {
       dest=new String(buffer,0,n,"UTF-8").getBytes("GBK");
       outputStream.write(dest);
    }
    

    也失败,发送请求 pending ,响应是 504 Gateway Time-out nginx ,弹不出文件保存框。

    10 条回复    2023-01-05 17:04:58 +08:00
    mejee
        1
    mejee  
       2023-01-05 11:23:52 +08:00
    第三段代码:
    1 、是不是卡在 br.readLine() 了?建议 加日志看看具体 pending 到哪个位置
    2 、浏览器下载文件,需要设置相关的响应头里的,可以查下相关资料
    3 、bw 是服务端对浏览器的输出流,应该不用关闭,可以 flush 一下
    w11ya
        2
    w11ya  
    OP
       2023-01-05 11:45:23 +08:00
    我在代码的最后加了个日志,日志内容输出了。浏览器下载文件我直接写 streamresponse.setContentType(application/octet-stream),也没用。txt 文件下载不了,但是可以下载 rar 文件,就是下到 99%就停了。已经 flush 了
    sparklee
        3
    sparklee  
       2023-01-05 12:05:57 +08:00
    文件写完直接 redirect 一个 文件下载地址,
    OctopusGO
        4
    OctopusGO  
       2023-01-05 13:30:04 +08:00
    编码转换的有错误,先转换成 UTF-8,然后再用 GBK 读取还原成字符串,再写出
    String s = new String(buffer,"UTF-8");
    String s2 = new String(s.getBytes("GBK"), "GBK");
    outputStream.write(s2.getBytes(),0,n);
    OpenSea
        5
    OpenSea  
       2023-01-05 13:31:02 +08:00
    bw.close()后再 br.close()
    OpenJdk
        6
    OpenJdk  
       2023-01-05 13:46:08 +08:00
    @OctopusGO
    String s = new String(buffer, "UTF-8");
    outputStream.write(s.geyBytes("GBK", 0, n)
    OpenJdk
        7
    OpenJdk  
       2023-01-05 13:46:30 +08:00
    OpenJdk
        8
    OpenJdk  
       2023-01-05 13:49:20 +08:00
    @OctopusGO
    你这样拿不到该字符串的 GBK 编码字节流。得这样
    String s = new String(buffer, "UTF-8");
    outputStream.write(s.geyBytes("GBK"), 0, n)
    w11ya
        9
    w11ya  
    OP
       2023-01-05 13:59:10 +08:00
    @OpenJdk 这个就是我尝试的那个吧
    w11ya
        10
    w11ya  
    OP
       2023-01-05 17:04:58 +08:00
    谢谢大佬们的回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1094 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 18:07 · PVG 02:07 · LAX 10:07 · JFK 13:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.