hierynomus / smbj

Server Message Block (SMB2, SMB3) implementation in Java
Other
713 stars 180 forks source link

How to download file in spring boot? #580

Open liu-xinhui opened 4 years ago

liu-xinhui commented 4 years ago
public static void download(String filename, HttpServletResponse response) {
        String fileNameEncode = new String(filename.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileNameEncode);
        response.setContentType("application/octet-stream");
        try (DiskShare share = getShare()) {
            System.out.println(share.fileExists(filename));
            com.hierynomus.smbj.share.File fileRead = share.openFile(
                    filename,
                    EnumSet.of(AccessMask.GENERIC_READ),
                    null,
                    SMB2ShareAccess.ALL,
                    SMB2CreateDisposition.FILE_OPEN,
                    null);
            InputStream is = fileRead.getInputStream();
            int available = is.available();
            System.out.println(available);
            IOUtils.copy(is, response.getOutputStream());
            response.flushBuffer();
            is.close();
            fileRead.close();
        } catch (IOException e) {
            throw new RuntimeException();
        }
    }

share.fileExists(filename) is true ,but is.available() always 0, file is 0kb when browser download

hierynomus commented 3 years ago

The FileInputStream that is returned is always indeed returning 0 for available. As you can read in the JavaDoc for InputStream:

Returns an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking, which may be 0, or 0 when end of stream is detected. 

So 0 can mean either End-of-Stream has been reached, or there are 0 bytes available without issuing a blocking call. The latter is true.

If you want to easily copy the contents to an OutputStream use the File.read(OutputStream) call instead.

hierynomus commented 3 years ago

An option would be to do a call on available() to pre-fill the buffer, that would prevent this from happening.