255 / 216 Exception in thread "main" java.io.IOException: Stream Closed at java.base/java.io.FileInputStream.read0(Native Method) at java.base/java.io.FileInputStream.read(FileInputStream.java:231)
换成 java.util.stream 也是一样的
java
1 2 3 4 5 6 7
final var intStream = IntStream.range(1, 4); // 第一次读取 intStream.boxed() .forEach(System.out::println); // 第二次读取 intStream.boxed() .forEach(System.out::println);
控制台打印如下
shell
1 2 3 4 5 6 7 8 9 10
1 2 3 Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed at java.base/java.util.stream.AbstractPipeline.<init>(AbstractPipeline.java:203) at java.base/java.util.stream.ReferencePipeline.<init>(ReferencePipeline.java:96) at java.base/java.util.stream.ReferencePipeline$StatelessOp.<init>(ReferencePipeline.java:800) at java.base/java.util.stream.IntPipeline$1.<init>(IntPipeline.java:174) at java.base/java.util.stream.IntPipeline.mapToObj(IntPipeline.java:174) at java.base/java.util.stream.IntPipeline.boxed(IntPipeline.java:233)
@PostMapping("/upload") public String inputStream( @RequestParam("file") final MultipartFile file ) { final Consumer<String> task = fileName -> { try ( final var output = new FileOutputStream("/Users/wuhunyu/Desktop/" + fileName); final var input = file.getInputStream() ) { input.transferTo(output); } catch (IOException e) { throw new RuntimeException(e); } };
/** * Returns an {@link java.io.InputStream InputStream} that can be * used to retrieve the contents of the file. * * @return An {@link java.io.InputStream InputStream} that can be * used to retrieve the contents of the file. * * @throws IOException if an error occurs. */ @Override public InputStream getInputStream() throws IOException { if (!isInMemory()) { return Files.newInputStream(dfos.getFile().toPath()); }
if (cachedContent == null) { cachedContent = dfos.getData(); } return new ByteArrayInputStream(cachedContent); }
/** * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> * compliant {@code multipart/form-data} stream. * * @param ctx The context for the request to be parsed. * * @return A list of {@code FileItem} instances parsed from the * request, in the order that they were transmitted. * * @throws FileUploadException if there are problems reading/parsing * the request or storing files. */ public List<FileItem> parseRequest(final RequestContext ctx) throws FileUploadException { final List<FileItem> items = new ArrayList<>(); boolean successful = false; try { final FileItemIterator iter = getItemIterator(ctx); final FileItemFactory fileItemFactory = Objects.requireNonNull(getFileItemFactory(), "No FileItemFactory has been set."); final byte[] buffer = new byte[Streams.DEFAULT_BUFFER_SIZE]; while (iter.hasNext()) { if (items.size() == fileCountMax) { // The next item will exceed the limit. throw new FileCountLimitExceededException(ATTACHMENT, getFileCountMax()); } final FileItemStream item = iter.next(); // Don't use getName() here to prevent an InvalidFileNameException. final String fileName = item.getName(); final FileItem fileItem = fileItemFactory.createItem(item.getFieldName(), item.getContentType(), item.isFormField(), fileName); items.add(fileItem); try { Streams.copy(item.openStream(), fileItem.getOutputStream(), true, buffer); } catch (final FileUploadIOException e) { throw (FileUploadException) e.getCause(); } catch (final IOException e) { throw new IOFileUploadException(String.format("Processing of %s request failed. %s", MULTIPART_FORM_DATA, e.getMessage()), e); } final FileItemHeaders fih = item.getHeaders(); fileItem.setHeaders(fih); } successful = true; return items; } catch (final FileUploadException e) { throw e; } catch (final IOException e) { throw new FileUploadException(e.getMessage(), e); } finally { if (!successful) { for (final FileItem fileItem : items) { try { fileItem.delete(); } catch (final Exception ignored) { // ignored TODO perhaps add to tracker delete failure list somehow? } } } } }
第 34 行,出现了一个流复制.其中,输入流来源于请求,输出流如下源码.创建了一个临时文件
java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/** * Returns an {@link java.io.OutputStream OutputStream} that can * be used for storing the contents of the file. * * @return An {@link java.io.OutputStream OutputStream} that can be used * for storing the contents of the file. * */ @Override public OutputStream getOutputStream() { if (dfos == null) { final File outputFile = getTempFile(); dfos = new DeferredFileOutputStream(sizeThreshold, outputFile); } return dfos; }