首页 > 代码库 > Java IO在实际开发中的应用

Java IO在实际开发中的应用

 

  IO是java绕不过去的槛,在开发中io无处不在, 正如同 世界上本没有路,java io写多了,也就知道了大体是什么意思,在读完thinking in java 感觉就更清晰了,结合具体的业务场景,整理一下 ,什么是IO。为什么JAVA要这么设计IO。

先来一道开胃菜

 我想要读取控制台输入的字符

技术分享View Code

  解释一下:我从控制台读取一行字符,然后打印一下。这就是一个简单的流了。

  整理一下: 就是我先 得到一个用于读取 控制台输入的流,然后 我·打印我得到的东西,这里有个细节就是 流一定得关闭,这是底线,关闭的顺序:先声明的后关闭

  稍微深入一点。我用Inputstream 去读取字符串并转化为想要的编码格式

技术分享View Code

   这就偏实际一点,当你拿到一个字符串的时候,读取的时候,有一个细节:最好加上编码格式

   解释一下:实际上读取的地方 只有这一点 line = bf.readLine() ,那么之前的是做什么呢,  我其实是在组装我想要的铲子。这也是 开发中比较常用的“包装器模式”

                        我想把字符串转为贴合实际的ByteArrayInputStream, 再转化为更常用的Reader(InputStreamReader)  再包装上buffer(BufferedReader)。 

当我选择输出的时候:

       当我查看我以前的开发记录时,发现实际业务中 绝大多数输出都是输出到文件的。想找一个简单的输出示例,并不容易

技术分享View Code

  输出的地方其实很简单: writer.write(str); 其他的地方 建立服务器连接,将str写到短信中和此处关系不大,需要注意 :无论是输入输出,用完了一定关闭流,这是底线 

 我有一文件

  文件读写才是一个真正的业务场景中占比绝大多数的。

 文件的基本操作 

技术分享View Code

在java中 File 就是 File , 它既可以是具体的文件,也可以是一个文件目录

读写文件总体步骤

当你读写文件的时候,看到直接读取字节实际上应用更广一点,当然用读取字符也是占很大比重,所以,这个问题就丢给各位读者,到底是想用哪个。反正都行。

技术分享View Code
技术分享View Code

  移动文件:实际上就是从一个文件中读取文件,然后写到另一个文件中,这算是一个非常详细的例子。分析代码:我想判断源文件是否存在,我再去创建目标文件夹和目标文件,当然,你也可以不用mkdir()

直接用 mkdirs()也行。

 当然我写文件时的数据(调用write()方法传入的数据)不一定是来自文件也有可能来自一个list,一个byte[]数组。

技术分享View Code
技术分享View Code

读写图片

技术分享View Code
 1     boolean isJob = etlTrans.getFromKjb();
 2         byte[] xml = etlTrans.getXml();
 3         ByteArrayInputStream bais = new ByteArrayInputStream(xml);
 4         TransMeta transMeta = null;
 5         JobMeta jobMeta = null;
 6         int imageWidth = 1400;// 图片的宽度
 7         int imageHeight = 900;// 图片的高度
 8         int wordWidth = 6;
 9         BufferedImage image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
10         Graphics graphics = image.getGraphics();
11         // 字体不支持时,中文就显示口口口了
12         graphics.setFont(new java.awt.Font("宋体", java.awt.Font.BOLD, 20));
13         // Font oldFont = graphics.getFont();
14         graphics.setColor(Color.WHITE);
15         graphics.fillRect(0, 0, imageWidth, imageHeight);

读写xml文件

技术分享View Code

xml文件读写,实际上也是一样的,只不过调用的是xml提供的读写工具类 

分文件写数据

 1 private void writeLog(FileOutputStream writer,
 2             List<ExceptionLog> cellExceptionLogs) throws IOException {
 3         StringBuilder builder = new StringBuilder();
 4         int len = cellExceptionLogs.size();
 5         for (int i = 0; i < len; i++) {
 6             ExceptionLog exceptionLog = cellExceptionLogs.get(i);
 7             processSystemLogData(exceptionLog, builder);
 8             if ((i + 1) % 500 == 0) {
 9                 writer.write(builder.toString().getBytes("UTF-8"));
10                 writer.flush();
11                 builder = null;
12                 builder = new StringBuilder();
13             }
14         }
15         if (len % 500 != 0) {
16             writer.write(builder.toString().getBytes("UTF-8"));
17             writer.flush();
18         }
19     }
20     private void processSystemLogData(ICellExceptionLog exception,
21             StringBuilder builder) {
22         builder.append(exception.getId() + Constant.REPORTUNITSEPARATOR);
23         builder.append(exception.getCode() + Constant.REPORTUNITSEPARATOR);
24         builder.append(exception.getName() + Constant.REPORTUNITSEPARATOR);
25         builder.append(exception.getDescription()+ Constant.REPORTUNITSEPARATOR);
26         builder.append("\r\n");
27     }

综合应用:编写一个页面,提供给用户下载数据。用户选择下载位置

 本质上是一样,只不过输出的流特殊一点(参考于java web文件下载功能实现)

第一步:写一个提供给用户的按钮

<a href="http://www.mamicode.com/day06/ServletDownload?filename=cors.zip">压缩包</a>  

第二步:编写对应的servlet方法。一共分两步:把文件读入文件流,把文件流内的数据写入到response中(response.getOutputStream().write(bytes, 0, bytes.length);)

技术分享View Code

 

断点续传 

   所谓断点续传 就是文件已经下载的地方开始继续下载。所以在客户端浏览器传给 Web服务器的时候要多加一条信息--从哪里开始。

断点续传的简单实例:

这是浏览器想要断点续传的时候发给服务器的信息

//        GET /down.zip HTTP/1.0         
//        User-Agent: NetFox         
//        RANGE: bytes=2000070-         
//        Accept: text/html, image/gif, image/jpeg, *; q=.2, *; q=.2 
//        上边的信息,是浏览器发给web用户的断点续传的信息

 

服务器的操作: 这是一段简单的模拟从一定位置些文件的代码

//假设从 2000070 处开始保存文件,代码如下:          
        RandomAccess oSavedFile = new  RandomAccessFile("down.zip","rw");           
        long nPos = 2000070;           
        // 定位文件指针到 nPos 位置          
        oSavedFile.seek(nPos);           
        byte[] b = new byte[1024];           
        int nRead;           
        // 从输入流中读入字节流,然后写到文件中          
        while((nRead=input.read(b,0,1024)) > 0)           
        {           
        oSavedFile.write(b,0,nRead);   

 

实际上,sevlet断点续传肯定不是这么简单,但是总体思路一致,我犹豫好久,最终还是把真正用于web项目的断点续传的服务器操作贴出(虽然我已经去了大多数和断点续传无关的业务逻辑,但是代码还是稍显复杂)

技术分享View Code

 

服务器操作完成之后返回的相应信息: 可以清楚的看到比普通的返回信息多了一个content-range

//Content-Length=106786028         
//Content-Range=bytes 2000070-106786027/106786028         
//Date=Mon, 30 Apr 2001 12:55:20 GMT         
//ETag=W/"02ca57e173c11:95b"        
//Content-Type=application/octet-stream         
//Server=Microsoft-IIS/5.0         
//Last-Modified=Mon, 30 Apr 2001 12:55:20 GMT  

当然实际项目都是多线程的,可以参考Java--使用多线程下载,断点续传技术原理(RandomAccessFile)

RandomAccessFile的常用方法介绍 可以参考java的RandomAccessFile类

 

给你一数据库

技术分享数据库中读取记录代码

 一般情况下,web项目采用一些orm框架足以支撑,数据库字段的读写,但是,有时候为了效率或者是特有的业务要求。会自己编写dao层支持。

而在读取数据库记录,写入Map的时候,如何读取一些特殊字段,比如Blob, 上述代码就是描述如何读取blob字段

 IO概括:

 文件的读写 ,在java中是非常常用。

 而设计者设计读写控制的时候,也整理的颇为详细,可能的结果就是,给调用者带来很大的困惑,这么多类,咋用。

 其实完全不用担心:java写文件只有三步,百变不离其宗

    1:我找到三样东西:   铲子(IO工具类); 沙子(我要读取的数据); 篓子(我要放的东西)

    2:用铲子把沙子放到篓子里

    3:我把铲子还给人家

  至于我用 何种铲子,我要铲的是沙子 还是面粉,我要放到篓子还是框子里。先别管,也别上来就看那个javaIIO的类示意图   

按铲子区分:一般单一的铲子不适用,需要组合多种功能

  java中有读写字符的(reader/writer) 读写字节的(inputstream,outputstream)。自由选择

  java按照功能 还会有 filereader xmlreder imgio   buffereader 等

按照沙子来看:

  字符串,byte[] , List<T>,数据库查询的结果集

按照篓子来看

  可以放到Map String 图片 文件 xml

对不起,非常抱歉的是,这是我之前的博客,copy过来,结果发现折叠的代码找不到了,我会马上整改 ,如果有谁知道以前的博客删除之后放到哪了,不胜感激

   

  

  

Java IO在实际开发中的应用