当前位置: 首页 > news >正文

淄博网站制作设计定制那些行业需要做网站

淄博网站制作设计定制,那些行业需要做网站,wordpress php 5.2,成都龙泉建设网站相信很多人对于java文件下载的过程都存在一些疑惑#xff0c;比如下载上传文件会不会占用vm内存#xff0c;上传/下载大文件会不会导致oom。下面从字节流的角度看下载/上传的实现#xff0c;可以更加深入理解文件的上传和下载功能。 文件下载 首先明确#xff0c;文件下载…相信很多人对于java文件下载的过程都存在一些疑惑比如下载上传文件会不会占用vm内存上传/下载大文件会不会导致oom。下面从字节流的角度看下载/上传的实现可以更加深入理解文件的上传和下载功能。 文件下载 首先明确文件下载不仅仅只有下载方还有服务端也就是返回文件的服务器 那么看一个简易文件服务器返回下载的文件。 服务端 这里是使用springMvc实现 GetMapping(download)public void downFile(HttpServletResponse response) throws IOException {response.setContentType(application/octet-stream);response.setHeader(Content-Disposition, attachment; filename test.jhprof);File file new File(D:\\heap\\heapDump.hprof);InputStream in new FileInputStream(file);OutputStream out response.getOutputStream();byte[] buffer new byte[1024];int len 0;while ((len in.read(buffer)) 0) {out.write(buffer, 0, len);}in.close();out.close();}这里每次从文件流中读取1024个字节输出是因为如果读取太多字节会给内存造成压力我们这里使用的是java的堆内存。如果直接完整读取整个文件那么可以导致oom。 java.lang.OutOfMemoryError: Java heap space客户端 URL url new URL(http://localhost:8062/fallback/download);URLConnection conn url.openConnection();InputStream in conn.getInputStream();FileOutputStream fileOutputStream new FileOutputStream(D:\\tmp\\a.hrpof);byte[] buffer new byte[1024];int len 0;while ((len in.read(buffer)) 0) {fileOutputStream.write(buffer, 0, len);}in.close();fileOutputStream.close();同样在下载文件时也需要注意不要一次读取特别多的字节数 测试过程发现由于TCP发送缓冲区和接受缓冲区有限当缓冲区满之后就会阻塞例如下载方的速度满服务端的文件不断写到缓冲区缓冲区满了就无法继续写入那么就会导致在执行write方法时暂时阻塞。等到接收端接受到数据了才能继续写入。 文件上传 服务端 http是支持多个文件进行上传的文件数据都在请求体中多个文件之间可以通过分隔符区分 例如上传两个文本文件 请求大概长这样 1.HTTP上传methodpost,enctypemultipart/form-data; 2.计算出所有上传文件的总的字节数作为Content-Length的值 3.设置 Content-Type:multipart/form-data; boundary----WebKitFormBoundaryJ9RUA0QCk13RaoAp 4.多个文件数据:请求体 ------WebKitFormBoundaryJ9RUA0QCk13RaoAp Content-Disposition: form-data; namepic; filenamethunder.gif Content-Type: image/gif 这中间是文件的二进制数据------WebKitFormBoundaryJ9RUA0QCk13RaoAp Content-Disposition: form-data; namepic; filenameuuu.gif Content-Type: image/gif 这中间是文件的二进制数据 ------WebKitFormBoundaryJ9RUA0QCk13RaoAp-- 服务端使用springMvc接收上传文件的写法多个文件 RequestMapping(method RequestMethod.POST,value /uploadModel)public void uploadModel(RequestPart(value file, required true) ListMultipartFile file, RequestParam Integer type) {··········}这样就可以直接获取到上传的文件。 具体接受过程还要看springMvc的实现 在doDispatch方法中会是否按照文件进行处理 判断方式也很简单检查请求头的multipart Overridepublic boolean isMultipart(HttpServletRequest request) {return StringUtils.startsWithIgnoreCase(request.getContentType(), multipart/);}如果是文件类型那么就要通过IO流将文件下载到本地 springMvc的大致实现如下 原代码位置org.apache.tomcat.util.http.fileupload.FileUploadBase#parseRequest FileItemIterator iter getItemIterator(ctx);FileItemFactory fileItemFactory Objects.requireNonNull(getFileItemFactory(), No FileItemFactory has been set.);final byte[] buffer new byte[Streams.DEFAULT_BUFFER_SIZE];//8KB的字节数组用于读取字节流while (iter.hasNext()) {final FileItemStream item iter.next();// Dont use getName() here to prevent an InvalidFileNameException.final String fileName ((FileItemStreamImpl) item).getName();FileItem fileItem fileItemFactory.createItem(item.getFieldName(), item.getContentType(),item.isFormField(), fileName);items.add(fileItem);try {Streams.copy(item.openStream(), fileItem.getOutputStream(), true, buffer);} catch (FileUploadIOException e) {throw (FileUploadException) e.getCause();} catch (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;根据分隔符找出上传的多个文件进行读取字节流同时创建本地文件写入到本地文件这里循环通过8kb数组读取到内存再写到文件是为了防止文件过大造成占用内存大。 public static long copy(InputStream inputStream,OutputStream outputStream, boolean closeOutputStream,byte[] buffer)throws IOException {OutputStream out outputStream;InputStream in inputStream;try {long total 0;for (;;) {int res in.read(buffer);if (res -1) {break;}if (res 0) {total res;if (out ! null) {out.write(buffer, 0, res);}}}if (out ! null) {if (closeOutputStream) {out.close();} else {out.flush();}out null;}in.close();in null;return total;} finally {IOUtils.closeQuietly(in);if (closeOutputStream) {IOUtils.closeQuietly(out);}}}从这里我们也能看出来http请求不并不是tomcat服务器接收进完全接收的而是先接收请求头进行就开始进行处理了至于后面要不要读取请求提如何读取就要看程序员的代码了这也是程序员可以控制的。 客户端 文件上传的客户端逻辑比较复杂 package javaio;import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.HashMap; import java.util.Map;/*** author liuxishan 2023/9/3*/public class FileUpload {public static void main(String[] args) {String reslut null;MapString, File files new HashMap() {{put(0.png, new File(C:\\Users\\lxs\\Desktop\\0.png));put(1.jpg, new File(C:\\Users\\lxs\\Desktop\\1.png));put(big.herof, new File(D:\\heap\\heapDump.hprof));}};try {String BOUNDARY java.util.UUID.randomUUID().toString();String PREFIX --, LINEND \r\n;String MULTIPART_FROM_DATA multipart/form-data;String CHARSET UTF-8;URL uri new URL(http://localhost:8062/fallback/uploadModel?type1);HttpURLConnection conn (HttpURLConnection) uri.openConnection();// conn.setChunkedStreamingMode(0);conn.setReadTimeout(100 * 1000);conn.setDoInput(true);// 允许输入conn.setDoOutput(true);// 允许输出conn.setUseCaches(false);conn.setRequestMethod(POST); // Post方式conn.setRequestProperty(connection, keep-alive);conn.setRequestProperty(Charsert, UTF-8);conn.setRequestProperty(Content-Type, MULTIPART_FROM_DATA ;boundary BOUNDARY);conn.connect();// 首先组拼文本类型的参数StringBuilder sb new StringBuilder();OutputStream outStream conn.getOutputStream();outStream.flush();// 发送文件数据if (files ! null) // for (Map.EntryString, File file : files.entrySet()) {for (String key : files.keySet()) {StringBuilder sb1 new StringBuilder();sb1.append(PREFIX);sb1.append(BOUNDARY);sb1.append(LINEND);sb1.append(Content-Disposition: form-data; name\file\; filename\ key \ LINEND);sb1.append(Content-Type: multipart/form-data; charset CHARSET LINEND);sb1.append(LINEND);outStream.write(sb1.toString().getBytes());File valuefile files.get(key);InputStream is new FileInputStream(valuefile);byte[] buffer new byte[1024];int len 0;while ((len is.read(buffer)) ! -1) {outStream.write(buffer, 0, len);}is.close();outStream.write(LINEND.getBytes());}// 请求结束标志byte[] end_data (PREFIX BOUNDARY PREFIX LINEND).getBytes();outStream.write(end_data);outStream.flush();// 得到响应码 // success conn.getResponseCode()200;InputStream in conn.getInputStream();InputStreamReader isReader new InputStreamReader(in);BufferedReader bufReader new BufferedReader(isReader);String line null;reslut ;while ((line bufReader.readLine()) ! null)reslut line;outStream.close();conn.disconnect();} catch (Exception e) {e.printStackTrace();}}}这里需要注意的是在使用HttpURLConnection 上传大文件时出现内存溢出的错误这让我产生了错觉输入和输出流咋会暂用内存不就是一个数据传送的管道么都没有把数据读取到内存中为撒会报错。。。然后就纠结了。。。 不过实在与原来的经验相违背然后写了一个示例直接从file中读出然后写入到输出流中发现并没有问题 查HttpURLConnection api发现其有缓存机制数据并没有实时发送到网络而是先缓存再发送导致内存溢出。 解决办法 httpConnection.setChunkedStreamingMode(0); //不使用HttpURLConnection的缓存机制直接将流提交到服务器上。 需要注意的是我们经常使用的hutool的http也存在这个问题 如果不指定chunkedStreamingMode也会出现oom的问题 对于大文件可以这么进行指定。 HttpResponse response HttpUtil.createPost(http://localhost:8062/fallback/uploadModel?type1).setChunkedStreamingMode(0).form(file, new File(D:\\heap\\heapDump.hprof)).execute();
http://www.pierceye.com/news/480132/

相关文章:

  • 医疗网站怎么做seo怎样通过网址浏览自己做的网站
  • 湖北现代城市建设集团网站wordpress用户头像插件
  • 徐州双语网站制作响应式网站开发pdf
  • 怎么做建设网站公司创建一个网站多少钱
  • 好看的扁平化网站wordpress插件编写
  • 深圳网站设计模板ps可以做网站动态图
  • 微信网站制作入门网站开发实施方案进度
  • 网站用户界面设计国内网站建设最好公司
  • 运城做网站费用高吗高端模板建站
  • 凡客诚品网站设计合肥网红打卡地
  • 淘宝网站代理怎么做的广西送变电建设公司铁塔厂网站
  • 自媒体网站开发网站的推广方式包括
  • 教育做的比较好的网站有哪些网站的建设及维护
  • dw设计做网站案例建设网站杭州
  • 做网站认证对网站有什么好处广西网站建设开发团队
  • 建一个网站需要哪些知识无锡大型互联网公司
  • 餐饮公司 网站建设做网站一年大概的盈利
  • 做金融怎么进基金公司网站免费行情软件网站游戏
  • 网站推广解释创立一个网站要多少钱
  • 绍兴专业网站建设公司大型网站建设哪家好
  • 天河网站设计响应式视频网站模板
  • 网站制作老了手机网站模板开发
  • 哪家网站建设比较好海拉尔建网站
  • 丹东网站推广海南行指专业网站开发
  • 网站如何调用手机淘宝做淘宝客中国企业网站查询
  • 淄博建设工程学校官方网站专门做商标的网站有哪些
  • 私人免费网站怎么下载企业网站设计方案
  • 做阿里巴巴网站找谁互联网推广公司
  • 网站如何做微信支付宝支付宝支付网页传奇发布网
  • 网站建设语录谷歌浏览器官网下载