大事记 --深夜篇

本次深夜,本人来记录一下新知道的,如何在JavaWeb工程中利用浏览器像服务器目录上传与下载文件。

所谓文件上传下载

本质是将文件以I/O流形式进行读写。从A以流形式传输到B,在经过还原,即可实现文件传输。
实现过程如下:

  1. 选中并提交要上传文件。
  2. 服务器以流形式接收。
  3. 写入到对应路径。
    主体就是这三步,具体对应代码逻辑如下:

//在jsp页面添加表单,并且必须有enctype="multipart/form-data"属性
 <form action="saveFile" method="post" enctype="multipart/form-data">
      请选择文件:<input type="file" name="fileName" value=""><br>
      <input type="submit" name="提交">
    </form>

效果图如下

java 对文件的上传和下载 javaweb实现文件上传下载_服务器



第二步可能稍微复杂,但是是比较容易的。

//在对应控制类中,以流形式接收该文件
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> itemList = upload.parseRequest(req);
for(var item : itemList){//加强for循环是为了防止表单一次性有过多文件传输
	String realName = item.getName();//注意此处获得的是文件真实文件名,也就是从盘符开始的
	String[] name = realName.split("\\\\");//此处四个\是因为\自身本为转义符,再加上split方法的特殊性。有兴趣的伙伴可以自行了解
	realName = name[name.length-1];//这才是文件的名称
	InputStream inputStream = item.getInputStream();//以流形式接收到文件自身内容
}

至此,第二步完成。不过需要说的特别是前两行代码。其实是用了外部封装的jar包(地址在后边)。毕竟站在巨人肩膀才能看的更远。其中的逻辑较为复杂,作者自身还是有点恍惚,就不做解释了。

这一步其实有两种实现方法 先来简单的,有兴趣的伙伴可以看看第二种原理。

item.write(new File("D://test/"+realFileName));//在上一个for循环中加入这一行就成功了,当然路径自选。

底层原理不外乎就是

OutputStream outputStream = new FileOutputStream("D://test/"+realFileName);//新建文件输入
	byte[] b = new byte[1024];//设定一次性写入大小
	int length = inputStream.read(b);//I/O流方式进行读取
	while(length!=-1){
		outputStream.write(b,0,length);//循环写入
		outputStream.flush();
		length = inputStream.read(b);
	}

这样我们就实现了文件向服务器的传输。经过本人无聊测试后,在局域网内是可以在不同计算机之间传递文件数据的。如果加入公网IP就不得而知了。待本人有需求的话,在来填这个问题的坑吧。

而文件的下载,几乎和上传的原理是相同的。

  1. 在浏览器发送需要下载的文件名
  2. 服务器接收并创建输入流读取该文件内容
  3. 相应对象创建输出流将内容响应回浏览器
    第一步这里不再赘述。而第二步比较麻烦的是要相应回浏览器,所以需要设置一些响应的头信息与格式
String fileName = request.getParameter("fileName");//首先get到文件名
InputStream inputStream = new FileInputStream("D://test/"+fileName);//在服务器路径下读取该文件
 fileName = URLEncoder.encode(fileName,"UTF-8");//处理中文
 //  调用静态常量进行拼接字符串
        response.setContentType("application/x-msdownload");
        response.setHeader("Content-disposition","attachment;filename="+fileName);
        将内容响应回浏览器
        OutputStream outputStream = response.getOutputStream();
        byte[] b = new byte[1024];
        int length = inputStream.read(b);
        while(length!=-1){
            outputStream.write(b,0,length);
            outputStream.flush();
            length = inputStream.read(b);
        }

尽管实现的手段略有不同,但是从思想的层面来说几乎是如出一辙。只是文件的流向不同而已。
夜深时分,自己的脑子也不太清楚。记录一下某段时间的“大”事吧,也希望对大家稍有帮助
差点忘了jar包的地址常用的是apache组织提供的一个包
commons-fileupload.jar
commons-io.jar
http://commons.apache.org/ 选择下载fileupload和io