Java IO使用和总结
来源:互联网 发布:java ee为什么这么小 编辑:程序博客网 时间:2024/06/05 23:59
Java IO使用和总结
上篇文章提到了NIO的使用,这篇总结下IO的使用;不详谈语法,仅分析特点,从而明确它们的使用范围,这样就能够在合适的场合想到并应用它们。
1.IO的数据源和输出目标
IO的数据源和输出目标大致分为以下几类:
1)文件
2)管道
3)网络连接
4)内存缓存
5)系统输入输出
下面逐一分析
2.文件
/**2.文件 * 你可以根据该文件是二进制文件还是文本文件来选择使用FileInputStream或者FileReader * 如果你需要跳跃式地读取文件其中的某些部分,可以使用RandomAccessFile * 注意: * 有时候你可能需要读取文件的信息而不是文件的内容,举个例子,如果你需要知道文件的大小 * 和文件的属性。对于目录来说也是一样的,比如你需要获取某个目录下的文件列表。通过File * 类可以获取文件和目录的信息。 */
3.管道
/**3.管道(在上一篇NIO的总结中提到了它,并且举了一个示例) * Java IO中的管道为运行在同一个JVM中的两个线程提供了通信的能力。 * 你不能利用管道与不同的JVM中的线程通信(不同的进程)。在概念上,Java的管道不同于Unix/Linux * 系统中的管道。在Unix/Linux中,运行在不同地址空间的两个进程可以通过管道通信。在Java中,通 * 信的双方应该是运行在同一进程中的不同线程。 * * 除了管道之外,一个JVM中不同线程之间还有许多通信的方式。实际上,线程在大多数情况下会传递 * 完整的对象信息而非原始的字节数据。但是,如果你需要在线程之间传递字节数据,Java IO的管道 * 是一个不错的选择。 * * 管道的本质是一样的,只是在应用时,在IO和NIO中的语法不同而已 */
4.网络连接
/**4.IO 网络 * Java网络API用来在不同进程之间建立网络连接,而Java IO则用来在建立了连接之后的进程之间交换数据 * 下面的一个写法,不使用FileInputStream而是InputStream,是因为可以这样的话还可以同时接收来自网络的输入,再 * 延伸一下,java.io.InputStream类是所有Java IO输入流的基类。如果你正在开发一个从流中读取数据的组件,请尝试 * 用InputStream替代任何它的子类(比如FileInputStream)进行开发。这么做能够让你的代码兼容任何类型而非某种确定 * 类型的输入流 ;同样的,OutputStream也是一样。如下面一个例子 */
/*下面的一个写法,不使用FileInputStream而是InputStream,是因为可以这样的话还可以同时接收来自网络的输入*/public class MyClass { public static void main(String[] args) { InputStream inputStream = new FileInputStream("c:\\myfile.txt"); process(inputStream); } public static void process(InputStream input) throws IOException { //do something with the InputStream }}
5.内存缓存
/**5.IO 读取或者获得字节(字符数组) 可以把这个理解为内存缓存 * 5.1 用ByteArrayInputStream或者CharArrayReader封装字节或者字符数组,然后从数组中读取数据成为流, * 以同样的方式也可以用于读取字符数组,只要把字符数组封装在CharArrayReader上就行了。 * byte[] bytes = new byte[1024]; * InputStream input = new ByteArrayInputStream(bytes); * * 5.2 把数据写到ByteArrayOutputStream或者CharArrayWriter中,只要调用toByteArray()或者toCharArray, * 所有写入的数据就会以数组的形式返回 * OutputStream output = new ByteArrayOutputStream(); * output.write("This text is converted to bytes".getBytes("UTF-8")); * byte[] bytes = output.toByteArray(); */
有一个深复制的问题,就可以使用这个思想来做; 如果一个对象数组List<Object>, 如何得到它的一份拷贝,我们所熟悉的add()方法,adllAll()方法,还有system.copy等都不能实现,我们需要的是一个新的List,而且其中的每一个对象都是新的,可以把Object 序列化,然后将Ist.LIst<Object>拷贝到内存中,以ByteArray的形式存放,然后从内存种读取这个 ByteArray到一个新的List<Object>中(反序列化),下面是示例:
/*引出一个深复制的问题,代码如下:*/public static <T> List<T> deepCopy(List<T> src) throws IOException, ClassNotFoundException { ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(byteOut); out.writeObject(src); ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray()); ObjectInputStream in = new ObjectInputStream(byteIn); @SuppressWarnings("unchecked") List<T> dest = (List<T>) in.readObject(); return dest; }
6.系统输入输出
/**6.替换系统流 系统输入输出 * System.in, System.out, System.err本身没什么可讲的。但是有一点;尽管System.in, System.out, * System.err这3个流是java.lang.System类中的静态成员(译者注:这3个变量均为final static常量), * 并且已经预先在JVM启动的时候初始化完成,你依然可以更改它们。只需要把一个新的InputStream设 * 置给System.in或者一个新的OutputStream设置给System.out或者System.err,之后的数据都将会在新 * 的流中进行读取、写入。如下案例: * * 注意:flush的调用,什么时候调用flush? * 1)FileOutPutStream继承outputStream,并不提供flush()方法的重写,所以无论内容多少write都会 * 将二进制流直接传递给底层操作系统的I/O,flush无效果 * 而Buffered系列的输入输出流函数单从Buffered这个单词就可以看出他们是使用缓冲区的,应用程序 * 每次IO都要和设备进行通信,效率很低,因此缓冲区为了提高效率,当写入设备时,先写入缓冲区, * 等到缓冲区有足够多的数据时,就整体写入设备,所以它需要使用flush方法手动强制写出; * 2)close()方法中包含了flush()的操作,但是马上就关闭流,所以如果想强制刷新缓冲区,然后继续使用 * 流的话,就用flush */
OutputStream output = new FileOutputStream("c:\\data\\system.out.txt");PrintStream printOut = new PrintStream(output);System.setOut(printOut)
下面讲述一些IO中的其他相关需要学习其特点和注意的地方
7
/**7.PushbackInputStream * 可以获取输入流之后,处理,然后再反过来放入输入源中。 */
8
/**8 关于流的整合问题 * Stream可以与Reader或者Writer整合 * Reader或者Writer可以与Buffer整合 */
9
/**9.之前说到了不在service层try catch,而是在方法体上throws异常:http://blog.csdn.net/Jintao_Ma/article/details/52853865 * 但是如果在service层关闭流的时候可能要用到try catch finally,这个时候,上层如何回复消息给用户? * 个人认为一个比较好的解决方法是:在service的方法体上加上返回值,然后将service内部的异常信息描 * 述成用户能识别的内容,之后放入返回值中,在controller层捕获异常, * 1)有异常 2)没有异常,那么有两种情况 * 2.1)service层的异常,2.2)确实没有异常 这三种情况都可以返回给用户
public static void main(String[] args) throws FileNotFoundException, IOException {try(FileInputStream fileInputStream = new FileInputStream(new File("test.txt"))){System.out.println("Channel2.main()");}}public BaseResult controllerMethod{ /*假设是controller层次*/BaseResult baseResult = new BaseResult();try {BaseResult = serviceMethod();} catch (Exception e) {BaseResult.setIsSuccess(false);BaseResult.serErrMsg("业务异常");}finally{return BaseResult;}}public BaseResult serviceMethod() throws Exception(){BaseResult baseResult = new BaseResult();try{InputStream input = new FileInputStream("c:\\data\\input-text.txt");doSomethingWithData(input);/*对输入流做一些处理*/}catch(IOException e){System.out.println(e.getMessage());baseResult.setIsSuccess(false);baseResult.serErrMsg("流异常");return baseResult; /*这个return 在finally执行后再执行*/}finally{input.close();/*关闭流*/}doOthers();/*可能会有异常,在方法体上抛出*/baseResult.setIsSuccess(true);return baseResult;}
那么还有没有其他的方法呢,其实是有的,那就是在关闭流的时候不使用finally,这样的话就不用try catch,就可以在方法体上throws异常,从而不影响我们之前文章总结的理论; JDK7及以上就提供了这种方法,称作try with resources, 顾名思义就是在try参数中加上资源,如下:
public static void main(String[] args) throws FileNotFoundException, IOException {try(FileInputStream fileInputStream = new FileInputStream(new File("test.txt"))){System.out.println("Channel2.main()");}}
另外再提到一点,关于异常处理,在C++中有异常模板,在Java中有异常框架,这一部分后面有时间再探究(这里备注下,提醒还有关于异常处理更标准的方法)
10
/**10.关于RandomAccessFile的使用 可以在任意位置读取文件 * seek 指定一个指针 * getFilePointer 方法 */
11
/**11.DataInputStream与DataOutputStream可以处理java基本类型的数据 */
12
/**12.ObjectInputStream与ObjectOutputStream 处理java序列化的对象 */
0 0
- Java IO使用和总结
- Java IO使用总结
- 【IO】java IO 总结
- java中的io使用常见规则总结
- Java中的IO技术使用总结
- Java文件IO的使用总结
- 常用文件和IO类使用总结
- java的io,nio和commons的io比较总结
- java的io,nio和commons的io比较总结
- [Java 12 IO] IO 总结
- 主题:java之IO 总结和笔记Java代码
- 【Java学习】Java IO-File类的理解和总结
- 【Java学习】Java IO-流概念理解和知识点总结
- Java IO Stream 总结
- java io流总结
- Java IO Stream 总结
- Java IO Stream 总结
- Java.io总结
- 也谈 Python 的中文编码处理
- Linux 双网卡配置两个IP同时只有一个会通的原因
- 视觉SLAM漫谈
- Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条(三十一)
- HTTP 状态代码
- Java IO使用和总结
- 基于Servlet的MVC模式Demo
- 欢迎使用CSDN-markdown编辑器
- ROS实践(4)-消息服务
- SQL游标(循环)单层和双层
- 用route命令添加永久路由
- 视觉SLAM漫谈(二):图优化理论与g2o的使用
- python的 a,b=b,a+b 和 a=b b=a+b 的区别
- UVA - 10125 Sumsets