关于request.getInputStream方法上传文件

之前有做过一个上传图片的功能,找到的资料全部都是用框架做的,当时为了尽快完成任务,就拿过来修修改改直接放线上了。对于我这样的菜鸟,任务虽然完成了,可当前更重要的是个人的技术提升。然后我又开始乱想了。经理说平时把基础多看看,嗯,上班也有一年了,年后我也写了日记进行了深刻的反思,然后重新给自己定位。理所当然的是最开始的一层,就是买家具用的人,对于各种技术都只是研究它是做什么的,怎么使用。只能拿过来用,也只会拿过来用。能力还不足以吃透它的底层和核心。再多的技术拿过来都只是会用。虽然这是做项目必备,而我也可以合格。但从个人角度出发,这样的事情重复多了,就真的是搬砖了。我想一步一步成为做家具的人,成为植树人···
想的再多不如踏实的搞点东西,嗯,开搞。任务完结后,我开始尝试用基础的servlet,来做这个功能。上传的原理我个人认为就是将本地文件作为输入流写入服务器上的某个目录下。嗯,按照这个逻辑,我开始找reques提供的方法,HttpServletRequest没有提供相关的方法,但是ServletRequest提供了一个getInputStream()方法,该方法返回的是检索ServletInputStream的request的实体的二进制数据。嗯,有点靠谱了。查看servletInputStream的api,解释是此抽象类提供一个从客户端读取二进制数据的输入流,包含一个高效的readLine的方法,是由container实现的。好了,输入流找到了,剩下的就是把读取到的数据写到某个目录下对应的文件里。
要一个jsp,提交数据
<body>
<form action="upload" method="post" enctype="multipart/form-data">
<input type="file" name="upload">
<input type="submit" value="submit">
</form>
</body>
剩下的就是在后台把数据给获取,然后写入。
public class UploadAction extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
InputStream in=req.getInputStream();

OutputStream out=null;
String path="C:\\Users\\Administrator\\Desktop\\promo\\sub\\test.jpg";
out=new FileOutputStream(path);
int c=0;
while((c=in.read())!=-1){
out.write(c);
out.flush();
}

in.close();
out.close();
}
}
我用图片测试的,跑完以后,路径下有了test.jpg,但是打开的话提示文件已经损坏。我了个大艹,又是这个问题!使用firebug看一下,提交的数据的什么的是没有问题的。这尼玛问题又是出在哪?按流程走,获取数据,写入数据,数据可以写入,没问题,那就是获取的读取的数据有问题了。将test.jpg改成test.txt跑完以后打开一看,文件竟然有三行明文字符,第一句对应的是Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryOgnVq83gcrdVAbmq,是boundary的值,第二句是Content-Disposition: form-data; name="upload"; filename="1.jpg",包含了jsp中file的参数名,filename的值是上传文件的名字。第三行Content-Type: image/jpeg,这些都是Header Field中的内容。第四行是空白。也就是说从第四行以后才是文件的内容,也就是ServletInputStream所谓的草泥马的request的实体的二进制数据!我英文很差啊! Retrieves the body of the request as binary data using a ServletInputStream,这操蛋的the body of the quest到底是啥玩意!好吧,先不管,知道问题在哪里了,那就绕过这个坑,既然获取的内容不完全是上传的文件内容,那就需要把不是文件的内容给丢掉。我的思路是,把getInputStream()或取的内容都先生成一个临时的txt文件,然后再从这个文件里读取真正的上传文件的内容。嗯,很可行。接下来就要引入一个新成员,RandomAccessFile.我跟它不熟,也是用到才去了解,嗯,此时此刻,它是我的英雄。随机文件存取流,能够在文件的任何位置查找或者写入数据。这个特性,是无敌的破防,无敌的固定伤害!好,代码继续改
public class UploadAction extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
InputStream in=req.getInputStream();

OutputStream out=null;
OutputStream fout=null;
String path="C:\\Users\\Administrator\\Desktop\\promo\\sub\\test.txt";
RandomAccessFile raf=new RandomAccessFile(path,"r");
String filePath="C:\\Users\\Administrator\\Desktop\\promo\\sub\\test.jpg";

out=new FileOutputStream(path);
fout=new FileOutputStream(filePath);
int c=0;
while((c=in.read())!=-1){
out.write(c);
out.flush();
}
this.log(raf.readLine());
this.log(raf.readLine());
this.log(raf.readLine());
this.log(raf.readLine());
int d=0;
while((d=raf.read())!=-1){
fout.write(d);
fout.flush();
}
fout.close();
in.close();
out.close();
}
}
跑完以后图片果然是正常的出来。然后继续改进,既然上传的图片的名字可以读取到,那就让再处理一下,让名字对应上
public class UploadAction extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
InputStream in=req.getInputStream();

OutputStream out=null;
OutputStream fout=null;
String path="C:\\Users\\Administrator\\Desktop\\promo\\sub\\temp.txt";

String filePath="C:\\Users\\Administrator\\Desktop\\promo\\sub\\";

out=new FileOutputStream(path);
int c=0;
while((c=in.read())!=-1){
out.write(c);
out.flush();
}
String fileName = null;
RandomAccessFile raf=new RandomAccessFile(path,"r");
this.log(raf.readLine());
String []tempName=raf.readLine().split(";");
for(String s:tempName){
if(s.contains("filename")){
String[] ss=s.split("=");
fileName=ss[ss.length-1];
}
}
this.log(raf.readLine());
this.log(raf.readLine());
fout=new FileOutputStream(filePath+fileName.replace("\"", ""));
int d=0;
while((d=raf.read())!=-1){
fout.write(d);
fout.flush();
}
fout.close();
in.close();
out.close();
raf.close();
File file=new File(filePath+"temp.txt".replace("\"", ""));
if(file.exists()){
if(file.delete()){
this.log("finished");
}

}
}
}
到了这里,上传文件的功能是已经实现了,不过还有一点,就是那个temp.txt文件,最后还要把它给删掉,这样就比较圆满一点,不然总觉的多了点什么
public class UploadAction extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
InputStream in=req.getInputStream();

OutputStream out=null;
OutputStream fout=null;
String path="C:\\Users\\Administrator\\Desktop\\promo\\sub\\temp.txt";

String filePath="C:\\Users\\Administrator\\Desktop\\promo\\sub\\";

out=new FileOutputStream(path);
int c=0;
while((c=in.read())!=-1){
out.write(c);
out.flush();
}
String fileName = null;
RandomAccessFile raf=new RandomAccessFile(path,"r");
this.log(raf.readLine());
String []tempName=raf.readLine().split(";");
for(String s:tempName){
if(s.contains("filename")){
String[] ss=s.split("=");
fileName=ss[ss.length-1];
}
}
this.log(raf.readLine());
this.log(raf.readLine());
fout=new FileOutputStream(filePath+fileName.replace("\"", ""));
int d=0;
while((d=raf.read())!=-1){
fout.write(d);
fout.flush();
}
fout.close();
in.close();
out.close();
raf.close();
File file=new File(filePath+"temp.txt".replace("\"", ""));
if(file.exists()){
if(file.delete()){
this.log("finished");
}

}
}
}
再跑一遍,嗯,没什么问题了,不过更大的问题又出来了,我上传图片什么的小文件是可以的,我手贱的上传了一部一个多G的电影,然后风扇响了,然后cpu的使用率猛窜到95%,然后我就两眼一黑,洗洗睡了···

时间: 2024-08-29 04:24:09

关于request.getInputStream方法上传文件的相关文章

httpclient 4.3 psot方法上传文件与参数 中文乱码解决

废话不多说,直接上有码的! 1 package httpclient; 2 3 import java.io.File; 4 import java.nio.charset.Charset; 5 6 import org.apache.http.Consts; 7 import org.apache.http.Header; 8 import org.apache.http.HttpEntity; 9 import org.apache.http.client.methods.Closeable

使用post方法上传文件的两种做法

项目需要使用HTTP协议中的POST方法上传文件,稍微总结了一下,将过程贴出来,方便以后参考.有两种方法,第一是使用NSMutableURLRequest完全从零开始设置,可以加深对HTTP协议的理解:第二种是直接使用别人封装好的代码,如AFNetworking. 方法一,从0开始文件上传 NSURL *url = [NSURL URLWithString:@"http://yo.diveinedu.com/upload.php"];NSMutableURLRequest *reque

用POST方法上传文件

文件上传分为客户端和服务器端 客户端可以通过form表单进行上传 客户端使用html表单进行上传 enctype = "multipart/form-data"用来指定表单编码数据方式 method = "POST"指明发送数据的方法 <form action = "upload.php" method = "POST" enctype = "multipart/form-data"> <

SpringMVC上传文件的三种方式(转载)

直接上代码吧,大伙一看便知 这时:commonsmultipartresolver 的源码,可以研究一下 http://www.verysource.com/code/2337329_1/commonsmultipartresolver.java.html 前台: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <%@ page language="java" contentTy

模拟POST上传文件

上传下载文件在浏览器里面都非常简单,上传文件在浏览器里就是几个标签,中间到底发生了什么我们全然不知,而下载文件更是简单——下载文件只需获得文件的地址以二进制的方式写出来就好.最近有个同学想在安卓里面做一个上传功能的App,最简单的莫过于HTTP的POST方法了(fork this  https://www.imququ.com/post/four-ways-to-post-data-in-http.html). 可以先观察下上传文件的HTTP Header: 可以看到Request Header

文件上传表单 上传文件的细节 文件上传下载和数据库结合

1 文件上传表单   1)上传文件的本质是文本复制的过程   2)技术层面,在Java中一定会用到IO操作,主要以二进制方式读写   3)传统方式下,对于上传文件字段不同的浏览器有着不同的解析方式,例如:     IE6:upfile=c:\aa\bb\a.JPG     非IE6: upfile=a.JPG   4)可以将form以MIME协议的方式将上传文件传递到服务端,服务端以二进制流的方式读写     代码:客户端form enctype="multipart/form-data&quo

Qt通过HTTP POST上传文件

本文使用Qt Creator用HTTP POST的方法上传文件,并给出一个上传文件的例程. 本文主要客户端,所以对于服务器端程序编写的描述会比较简略 服务器使用Django编写,django服务器接收文件的方法在文章http://www.cnblogs.com/fnng/p/3740274.html中有较为清晰的讲解,我搭建的服务器端程序除了没有网页客户端以及部分变量名称不同以外,基本上与这篇文章的服务器搭建过程一样. 如果服务器端程序发生变化,这篇文章后面给出的客户端例程可能就不再适用.因此如

利用put上传文件到服务器

#import "KUViewController.h" #import "KUProgress.h" @interfaceKUViewController ()<NSURLSessionTaskDelegate> //下载进度的类,继承UIview @property (weak, nonatomic) IBOutlet  KUProgress *progressView; @end @implementation KUViewController -

springMVC+spring+hibernate注解上传文件到数据库,下载,多文件上传

数据库 CREATE TABLE `annex` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `realName` varchar(36) DEFAULT NULL, `fileContent` mediumblob, `handId` bigint(20) DEFAULT NULL, `customerId` bigint(20) DEFAULT NULL, PRIMARY KEY (`id`), KEY `fk_id` (`handId`), CON