java基础知识--IO篇
来源:互联网 发布:网络电视直播在线看 编辑:程序博客网 时间:2024/05/22 02:10
一、文件下载
项目文件存入ambry文件服务器,并返回可访问url,利用url下载该文件。
public void downloadByURL(@Param("download")String download,@Param("description")String description, HttpServletRequest request, HttpServletResponse response){//这里description为文件名,用以下载的时候显示。 if(!description.endsWith(".zip")){ description = description+".zip"; }//对response头进行设置 response.reset(); response.setContentType("application/octet-stream"); response.setCharacterEncoding("UTF-8"); //设置文件下载是以附件的形式下载 response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", description)); try { //根据文件url链接,获取文件字节数组 byte[] buffer = HTTPDownload.downLoadFromUrl(download); //从response头获取输出流,并向里面写 OutputStream out = response.getOutputStream(); //向流里面写,此时浏览器便能监听到 out.write(buffer); out.close(); } catch (IOException e) { e.printStackTrace(); } }
import java.net.HttpURLConnection;import java.net.URL;public static byte[] downLoadFromUrl(String urlStr) throws IOException { URL url = new URL(urlStr); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); //设置超时间为5秒 conn.setConnectTimeout(5*1000); //得到文件的输入流 InputStream inputStream = conn.getInputStream(); //将输入流转为字节数组 byte[] buffer = readInputStream(inputStream); return buffer; } /** * 从输入流中获取字节数组 * @param inputStream * @return * @throws IOException */ public static byte[] readInputStream(InputStream inputStream) throws IOException { byte[] buffer = new byte[4096]; int len = 0; //造个输出流,用来输出字节数组 ByteArrayOutputStream bos = new ByteArrayOutputStream(); while((len = inputStream.read(buffer)) != -1) { bos.write(buffer, 0, len); } bos.close(); inputStream.close(); return bos.toByteArray(); }
Content-disposition中Attachment和inline的区别
java web中下载文件时,我们一般设置 Content-Disposition 告诉浏览器下载文件的名称,是否在浏览器中内嵌显示.
- Content-disposition: inline; filename=foobar.pdf
- 表示浏览器内嵌显示一个文件
- Content-disposition: attachment; filename=foobar.pdf
- 表示会下载文件,如火狐浏览器中
但是我们使用的chrome,通常设置了默认下载地址,所以不会提示。如果没有设置,则会提示选择下载路径。
看如下代码 spring mvc中:
@ResponseBody @RequestMapping(value = "/download",produces="application/octet-stream") public byte[] downloadFile(HttpServletRequest request, HttpServletResponse response,String contentType2) throws IOException { byte[]bytes=FileUtils.getBytes4File("D:\\Temp\\cc.jpg"); response.addHeader("Content-Disposition", "inline;filename=\"a.jpg\""); return bytes; }
如上代码中是内嵌显示图片呢?还是会弹框下载呢?
答案是:弹框下载
为什么呢?设置为inline应该是内嵌显示啊!
因为response content type设置成了”application/octet-stream”
注意:我们说是内嵌显示还是下载,那 一定是针对可内嵌显示的类型 ,例如”image/jpeg”,”image/png”等.
看下面的例子:设置response content type为” image/jpeg “
@ResponseBody @RequestMapping(value = "/download",produces="image/jpeg") public byte[] downloadFile(HttpServletRequest request, HttpServletResponse response,String contentType2,String downloadType) throws IOException { byte[]bytes=FileUtils.getBytes4File("D:\\Temp\\cc.jpg"); response.addHeader("Content-Disposition", downloadType+";filename=\"a.jpg\""); return bytes; }
对于Content-type对照表可参照http://tool.oschina.net/commons
在浏览器中访问:http://localhost:8080/download?downloadType=inline 时就内嵌显示:
当在浏览器中访问:http://localhost:8080/download?downloadType=attachment 时就弹框下载.
二、文件上传
放一段hash大神的ambry文件上传。
public class HTTPUpload { private static final Logger log = LoggerFactory.getLogger(HTTPUpload.class); private final String ambryUrl; private final String tmpFilePath; public HTTPUpload(final String ambryUrl) { this.ambryUrl = ambryUrl;//笔记一,笔记二1 this.tmpFilePath = StrUtils.makeString(HTTPUpload.class.getResource("").getFile().toString(), "tmp"); File file1 = new File(tmpFilePath); //文件不存在则创建 if(!file1.exists()){ file1.mkdirs(); //设置文件权限 file1.setExecutable(true,false); file1.setReadable(true,false); file1.setWritable(true,false); } Scheduler scheduler = new Scheduler(); scheduler.schedule("50 13 * * *", new DeleteTask(tmpFilePath)); } public String uploadFile(MultipartFile file1, long size, String ServiceId, String owner, String fileFormat, String description) { HttpURLConnection connection = null; OutputStream os = null; DataInputStream is = null; InputStream inputStream = null; String message = "empty"; int count = 0; while (count <= 3) { try { //笔记二2 File file = new File(StrUtils.makeString(tmpFilePath, "/", file1.getOriginalFilename())); //笔记二3 file1.transferTo(file); //笔记三 if (!fileFormat.equals("image")) { inputStream = new StreamGenerator(file, tmpFilePath).getInputStream(); } else { inputStream = new FileInputStream(file); } //笔记四 int length = inputStream.available(); //笔记五 connection = (HttpURLConnection) new URL(ambryUrl).openConnection(); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "application/octet-stream"); //设置是否从httpUrlConnection读入,默认情况下是true; connection.setDoOutput(true); //设置是否向httpUrlConnection输出,默认为false connection.setDoInput(true); connection.setRequestProperty("x-ambry-blob-size", length + ""); connection.addRequestProperty("x-ambry-service-id", ServiceId); connection.addRequestProperty("x-ambry-owner-id", owner); connection.addRequestProperty("x-ambry-content-type", fileFormat); connection.addRequestProperty("x-ambry-um-description", description); connection.connect(); //笔记六 os = new BufferedOutputStream(connection.getOutputStream()); byte[] buffer = new byte[4096]; int bytes_read; //只要可以读取到数据,就输出写到buffer中 while ((bytes_read = inputStream.read(buffer)) != -1) { os.write(buffer, 0, bytes_read); } //数据读取完关闭inputStream os.close(); inputStream.close(); //笔记七 String location = connection.getHeaderField("Location"); return StrUtils.makeString(ambryUrl, location); } catch (Throwable e) { //笔记八 count++; try { TimeUnit.SECONDS.sleep(1L); } catch (InterruptedException e1) { } log.warn("file-upload-failed:" + JSON.toJSONString(file1) + "|||" + "{ServiceId:" + ServiceId + ",owner:" + owner + ",fileFormat:" + fileFormat + ",description:" + description + "}"); log.warn(ExceptionUtils.getStackTrace(e)); } finally { try { if (os != null) { os.close(); } } catch (IOException e) { log.warn(ExceptionUtils.getStackTrace(e)); } try { if (is != null) { is.close(); } } catch (IOException e) { log.warn(ExceptionUtils.getStackTrace(e)); } if (connection != null) { connection.disconnect(); } } } return null; }}
笔记一:
Class.getResource()与Class.getResourceAsStream()方法,但很多人还是不太懂它的用法,因为很多人(比如不久前的我)都不知道应该传怎么样的参数给它,当然,有些人己经用得如火纯青,这些人是不需要照顾的,在此仅给不会或者还不是很熟的人解释一点点。
比如我们有以下目录
|–project
|--src |--javaapplication |--Test.java |--file1.txt |--file2.txt|--build |--javaapplication |--Test.class |--file3.txt |--file4.txt
在上面的目录中,有一个src目录,这是JAVA源文件的目录,有一个build目录,这是JAVA编译后文件(.class文件等)的存放目录
那么,我们在Test类中应该如何分别获得
file1.txt file2.txt file3.txt file4.txt这四个文件呢?
首先讲file3.txt与file4.txt
file3.txt:
方法一:File file3 = new File(Test.class.getResource(“file3.txt”).getFile());
方法二:File file3 = new File(Test.class.getResource(“/javaapplication/file3.txt”).getFile());
方法三:File file3 = new File(Test.class.getClassLoader().getResource(“javaapplication/file3.txt”).getFile());
file4.txt:
方法一:File file4 = new File(Test.class.getResource(“/file4.txt”).getFile());
方法二:File file4 = new File(Test.class.getClassLoader().getResource(“file4.txt”).getFile());
很好,我们可以有多种方法选择,但是file1与file2文件呢?如何获得?
答案是,你只能写上它们的绝对路径,不能像file3与file4一样用class.getResource()这种方法获得,它们的获取方法如下
假如整个project目录放在c:/下,那么file1与file2的获取方法分别为
file1.txt
方法一:File file1 = new File(“c:/project/src/javaapplication/file1.txt”);
方法二:。。。没有
file2.txt
方法一:File file2 = new File(“c:/project/src/file2.txt”);
方法二:。。。也没有
总结一下,就是你想获得文件,你得从最终生成的.class文件为着手点,不要以.java文件的路径为出发点,因为真正使用的就是.class,不会拿个.java文件就使用,因为java是编译型语言嘛
笔记二:
在初始化HTTPUpload对象的时候,会在该类目录下创建个临时目录,D:/projectSource/*/target/classes/com/*/ambry/tmp,见笔记二1。
在使用上传方法时,在前面的目录下根据文件名new一个File,但file对象内容为空,见笔记二2。
将传过来的文件写入file对象中,见笔记二3。
笔记三:
如果文件不是image类型,则将文件压缩为zip之后得到输入流。如果是图片,则直接得到图片文件的输入流。
调用如下方法,返回zip文件的输入流
import java.util.zip.ZipEntry;import java.util.zip.ZipOutputStream;public class StreamGenerator { private static File file; private static String tempFilePath; public StreamGenerator(File file,String tempFilePath){ this.file = file; this.tempFilePath = tempFilePath; } /** * 压缩传入的文件,返回流 * @return inputstream */ public static InputStream getInputStream() { String zipName = IDGenerator.getID(Constants.PUBLIC_COMPONENT_SYSTEM); //判断是否有文件夹,如果没有就创建 File tempF = new File(tempFilePath); if(!tempF.exists()){ tempF.mkdirs(); } /** * 压缩并在指定目录生成临时zip文件 */ byte[] buffer = new byte[4096]; ZipOutputStream out = null; try { //在临时目录下根据前面生成的zip包名,new一个fileoutput(zipoutput)流 out = new ZipOutputStream(new FileOutputStream(tempFilePath + zipName + ".zip")); FileInputStream fileInput = new FileInputStream(file); //向流中加入zip实体(此时为空,名为文件名) out.putNextEntry(new ZipEntry(file.getName())); int temp = 0; //读取文件并打包 while ((temp = fileInput.read(buffer)) > 0) { out.write(buffer, 0, temp); } out.closeEntry(); fileInput.close(); out.close(); } catch(Exception ex){ ex.printStackTrace(); } /** * 把压缩包读取为输出流 */ //得到这个有内容的zip对象 File filezip = new File(tempFilePath + zipName + ".zip"); ByteArrayOutputStream byteOut = null; try { byteOut = new ByteArrayOutputStream(); FileInputStream FileIn = new FileInputStream(filezip); BufferedInputStream bufferInput = new BufferedInputStream(FileIn); int k = bufferInput.read(); while (k != -1) { byteOut.write(k); k = bufferInput.read(); } bufferInput.close(); FileIn.close(); } catch(Exception ex) { ex.printStackTrace(); } /** * 输出流转为uploadFile方法的输入流 */ ByteArrayInputStream inStream = new ByteArrayInputStream(byteOut.toByteArray()); return inStream; }}
此处为他人所写。根据输入流得到zip的输出流,得到字节数组,然后再回到输入流,感觉多此一举,也许可能存在流转换的问题,以后有时间去验证。
笔记四:
获得文件的可用大小,此处为ambry用,如果传错会报错。
笔记五:
向ambry发送http请求(post)
笔记六:
connection.getOutputStream()通过http连接,获取输出流。并包装成输出字节流,将zip或图片获取的输入流,写入此输出流。
笔记七:
location头里面的东西,就是文件存储后的唯一标识。
笔记八:
三次尝试机制,每次失败延迟1毫秒:TimeUnit.SECONDS.sleep(1L)。
- java基础知识----IO篇
- java基础知识--IO篇
- java io基础知识
- java中的IO基础知识
- java io基础知识
- java基础知识 ---io
- java基础知识IO流
- java io流基础知识
- Java IO基础知识(上)
- Java IO基础知识
- 【Java】IO流基础知识
- java基础知识---IO流
- Java基础知识-IO流
- Java基础知识-IO流
- Java基础知识梳理--IO
- java基础知识IO简单介绍
- Java基础知识回顾--IO流
- Java基础知识-IO流2
- mysql基本语句
- java 内存机制详解 (new 操作的执行原理)
- Spark入门(2)——生态系统
- 端口的状态详解
- linux命令学习与理解
- java基础知识--IO篇
- I2C 时序详解,精确到每一个时钟
- struts2入门,从下载到简单的配置
- 二叉树的建立和遍历
- 面试问题待解答
- FPGA中SRL16资源
- 如何理解beta分布
- Linux下安装部署Redis
- jQuery之ajax函数的一个小例子