代码之家  ›  专栏  ›  技术社区  ›  BingAring

REST方法调用上载的文件已损坏

  •  0
  • BingAring  · 技术社区  · 10 年前

    所以我在我的web应用程序中使用以下Rest方法来上传文件。当我上传文本文件时,它们会被正确保存,我可以打开它们。但在任何其他格式的情况下,即*。docx或*。pdf或*。jpg,这些文件以与原始文件相同的大小存储,但已损坏。代码如下:

    @POST
    @Consumes("multipart/form-data")
    public Response readFile() throws IOException, ServletException {
        Part filePart = request.getPart("c");
        InputStream f = filePart.getInputStream();
        String l = null;
        DataInputStream ds = new DataInputStream(f);
        File file = new File("c:\\temp\\" + getSubmittedFileName(filePart));
        try {
            BufferedWriter bw = new BufferedWriter(new FileWriter(file));
            while ((l = ds.readLine()) != null) {
                bw.write(l);
            }
            bw.flush();
            bw.close();
            return Response.status(201).entity("File Created").build();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Response.status(500).build();
    }
    

    html页面如下:

    <form action="api/fetch" method="post" enctype="multipart/form-data">
            <input id="c" name="c" type="file" aria-required="true"><br/><br/>
            <button type="submit">Submit</button>
    </form>
    

    我想一定有其他方式上传文件,而不是这样。我提到过 How to upload files to server using JSP/Servlet? 但我认为它并没有说明如何处理文件扩展名。那么,我的代码出了什么问题?

    1 回复  |  直到 9 年前
        1
  •  3
  •   SubOptimal    10 年前

    我相信错误就在这里

    DataInputStream ds = new DataInputStream(f);
    ...
    while ((l = ds.readLine()) != null) {
    

    从…起 DataInputStream.readLine Javadoc

    此方法无法将字节正确转换为字符。

    您应该使用 FileInputStream 而不是 DataInputStream 这个 文件输入流类 将所有文件视为字节。除了上述问题 readLine 在读取输入文件中的所有换行符时也会删除。

    编辑 有关演示,请参阅下面的小片段。

    文件 dummy.txt 包含

    foo
    bar
    

    后面的换行符 foo 是单身 \n 。在十六进制转储中

    66 6F 6F 0A 62 61 72
    

    现在使用 数据输入流 一次用 文件输入流类

    try (DataInputStream ds = new DataInputStream(new FileInputStream("dummy.txt"));
            Writer bw = new BufferedWriter(new FileWriter("out_writer.txt"))) {
        String l;
        while ((l = ds.readLine()) != null) {
            bw.write(l);
        }
    }
    try (InputStream in = new FileInputStream("dummy.txt");
            OutputStream out = new FileOutputStream("out_inputstream.txt")) {
        byte[] buffer = new byte[8192];
        int readBytes = -1;
        while ((readBytes = in.read(buffer)) > -1) {
            out.write(buffer, 0, readBytes);
        }
    }
    

    输出文件为

    out_writer.txt

    ASCII: foobar
    hex  : 66 6F 6F 62 61 72
    

    输出输入流.txt

    ASCII: foo
           bar
    hex  : 66 6F 6F 0A 62 61 72
    

    如您所见 0A ( \n个 )在 数据输入流 实例这个点画 line break 乱码输出文件。