IO流的典型使用方式

1、缓存输入文件

BufferedReader in=new BufferedReader( new FileReader(文件名字) );

String s;

StringBuilder sb=new StringBuilder();

while((s=in.readLine())!=null){

  sb.append(s+"\n");
} in.close();

  字符串sb用来存储文件的内容。

2、从内存输入

  借助上一步的sb里面保存的文件的内容来进行处理,将内存中的内容输出到控制台。

  StringReader in=new StringReader(sb);

  while((int c=in.read())!=-1){

    System.out.print((char) c);
  }

  

3、格式化的内存输入

4、基本的文件输出

  FileWriter对象可以向文件写入数据。首先,创建一个与指定文件连接的FileWriter。实际上,我们通常会将其用BUfferedWriter包装一下用于缓冲输出。PrintWriter可以对数据进行格式化输出,方便阅读。

5、存储和恢复数据

  如果我们使用DataOutputStream输出数据,java保证我们可以使用DataInputStream准确的读取数据。

6、读写随机访问文件

  使用RandomAccessFile,类似于组合使用了DataInputStream和DataOutputStream(因为他们实现了同样的接口:DataInput和DataOutput)。另外,利用seek()可以再文件中到处移动,随便修改文件中的某个值。

7、管道流

  PipedInputStream ,PipedOutputStream ,PipedReader和 PipedWriter的价值在理解多线程之后就会体现出来。因为管道流用于任务间的通信。

文件读写的实用工具

  一种很常见的任务就是将文件读入到内存修改后在保存到外存中。TextFile类用来简化对文件的读写操作。

标准I/O

  标准I/O这个词是借鉴与Unix中的“程序所使用的单一信息流”这个概念。程序的所有输入都来自于标准输入,程序的所有输出都可以发送到标准输出,以及所有错误信息都可以发送到标准错误。标准I/O的意义在于:我们可以很容易的将程序联起来,一个程序的标准输出可以作为另一个程序的标准输入。

1、从标准输入中获取

  我们将System.in包装为BufferedReader就必须用InputStreamReader将System.in转换为Reader。

  BufferedReader stdin=new BufferedReader( new InpueStreamReader(System.in) );

  String s;

  while((s=stdin.readLine())!=null && s.length!=0){

    //s就是相当于从标准流中读取到的数据
    System.out.print(s);//将数据送到控制台
  }

2、将Sysytem.out转换为PrintWriter

  PrinterWriter out=new PrintWriter(System.out,true);

  out.println("Hello World!");

3、标准I/O重定向

  重定向操作的是字节流,而不是字符流;因此我们使用的是InputStream和OutputStream,而不是Reader和Writer。

  BufferedStream in=new BufferedStream( new FileInputStream(输入文件名字) );

  PrintStream out = new PrintStream( new BufferedStream(  new FileInputStram(输出到的文件名字) ) );

  System.setIn(in);

  System.setOut(out);

NIO

  提高文件I/O和网络I/O都有帮助。速度的提高来源于所使用的结构更接近于操作系统执行I/O的方式:通道和缓冲器。(安利一波:这个地方java编程思想狙的例子还是挺恰当的且容易理解)我们只是从缓冲器获取数据,并没有和通道进行交互。而通道要么向缓冲器发送数据,要么从缓冲器获取数据。唯一直接与通道交互的缓冲器是ByteBuffer,他是一个可以存储未加工的字节的 缓冲器。他是一个相当基础的类:告知分配多少存储空间来创建一个ByteBuffer对象,并且还有一个方法选择集,用于以原始的字节形式或基本的数据类型输出和读取数据。但是没办法输出或读取对象,即使字符串对象也不可以。这种方式看着比较低级,但是正好,因为这是大多数操作系统中更有效的映射方式。

  将字节存放于ByteBuffer的方法之一:wrap(字节数组);

  FileChannel:旧I/O类库中有三个类被修改后用以产生FileChannel。这三个类是:FileInputStream(读一个文件),FileOutputStream(写一个文件)和RandomAccessFile(给一个文件随意位置添加内容)。他们都有一个getChannel方法用以返回一个FileChannel对象。一旦调用read()来告知FileChannel想ByteBuffer存储字节,就必须调用缓冲器上的flip(),让他做好让别人读取字节的准备。如果我们打算使用缓冲器执行进一步的read()操作,我们也必须要调用clear()来为每个read()做好准备。调用flip是为了告诉别人,我的缓冲器上的内容可以取下来,调用clear是为了告诉别人我的东西已经被取下来了,所以你可以继续read了。

  一个通道和另一个通道直接相连:TransferTo()和TransferFrom()。

1、转换数据

  缓冲器存放的是普通的字节,为了把他们转换为字符,有两种办法:①在输入的时候对其进行编码②在输出的时候对其进行解码

2、获取基本类型

  尽管ByteBuffer只有保存字节类型数据的功能,但是它可以从其所容纳的字节中产生各种不同的基本类型数据的方法。向ByteBuffer插入基本类型数据最简单的办法是:利用asCharBuffer()、asShortBuffer()等获取该缓冲器上的视图,然后使用视图上的put()方法。

3、视图缓冲器

  可以让我们通过某个特定的基本数据类型的视图查看其底层的ByteBuffer。正如上面视图提供给我们插入基本类型数据的方法,这样使得我们可以很方便的插入数据。当然,视图还可以允许我们从ByteBuffer一次一个地或者成批的读取基本类型数值。

4、用缓冲器操纵数据

  只有ByteBuffer可以和Channel打交道,IntBuffer、CharBuffer等等都是ByteBuffer的视图,即他们的底层都是通过ByteBuffer实现的。

5、缓冲器的细节

  mark    标记

  position位置

  limit      界限

  capacity 容量

  capacity()返回缓冲区容量

  clear()清空缓冲区,将position设置为0,limit设置为容量。通常调用此方法覆写缓冲区

  flip()将limit设置为position,position设置为0。此方法用于准备从缓冲区读取已经写入的数据

  limit()返回limit的值

  limit( int lim)设置limit的值

  mark()将mark设置为position

  position()返回position的值

  position( int pos)设置position的值

  remaining()返回limit-position

  hasRemaining()如果position与limit之间有元素,返回true

6、内存映射文件

  内存映射文件允许我们创建和修改那些因为太大而无法放入内存的文件。有了内存映射文件,我们就可以假定整个文件都放在内存中,而且完全把它当做一个大数组来进行处访问。这种方法极大地简化了修改文件的代码。另外,这种方式直接调用系统底层的缓存,没有JVM和系统之间的复制操作,所以效率大大的提高了。而且由于它这么快,还可以用它来在进程(或线程)间传递消息,基本上能达到和“共享内存页”相同的作用,只不过它是依托实体文件来运行的。

  MappedByteBuffer,这是一种特殊类型的直接缓冲器,从ByteBuffer继承而来。

  MappedByteBuffer对象的创建——FileChannel提供了map方法来把文件映射为MappedByteBuffer: MappedByteBuffer map(int mode,long position,long size); 可以把文件的从position开始的size大小的区域映射为MappedByteBuffer,mode指出了可访问该内存映像文件的方式,共有三种,分别为:
MapMode.READ_ONLY(只读): 试图修改得到的缓冲区将导致抛出 ReadOnlyBufferException。
MapMode.READ_WRITE(读/写): 对得到的缓冲区的更改最终将写入文件;但该更改对映射到同一文件的其他程序不一定是可见的(无处不在的“一致性问题”又出现了)。
MapMode.PRIVATE(专用): 可读可写,但是修改的内容不会写入文件,只是buffer自身的改变,这种能力称之为”copy on write”

7、对文件加锁

  java的文件锁直接映射到了本地操作系统的加锁工具。lock或者tryLock()。两者区别:lock是阻塞式的,tryLock是非阻塞式的。

压缩

  压缩类库是按照字节方式处理的。不过有时我们可能被迫使用两种类型的混合流(注意:我们可以通过InputStreamReader和OutputStreamWriter在两种类型之间转换)。

1、用GZIP进行简单压缩

  单个文件进行处理。压缩类的使用非常直观——直接将输出流封装成GZIPOutputStream或者ZipOutputStream,并将输入流封装成GZIPInputStream或者ZipInputStream即可。其他全部操作就是通常的IO读写。

2、用Zip进行多文件保存

  支持对多个文件进行压缩。这个类库是标准的Zip格式,所以能与当前那些可以通过因特网下载的压缩工具很好的协作。

3、Java档案文件

  Java ARcive——JAR文件。

对象序列化

  当你创建对象时,只要你需要,他就会一直存在。但是在程序终止时,无论如何他都不会继续存在。如果对象能够在程序不运行时仍能保存其信息,那将非常有用。这样,在下次运行程序时,该对象将被重建并且拥有的信息与程序上次运行时她所拥有的信息相同。当然,你也可以将对象信息也如文件或者数据库来实现相同的效果,但是在万物都是对象的精神中,如果能够将一个对象声明为持久化的,并为我们处理掉所有细节,那将会显得十分方便。

  Java的对象序列化将那些实现了Serializable接口的对象转换成一个字节序列,并能够在以后将这个字节序列完全恢复为原来的对象。“持久性”就会意味着对象的生存周期并不取决于程序是否在执行。

  通过将一个序列化对象写入磁盘,然后再重新调用程序时恢复该对象,就能够实现持久性的效果。必须在程序中显式地序列化(serialze)和反序列化还原(deserialize)。如果需要一个更严格的持久性机制,可以考虑Hibernate之类的工具。

  序列化主要是为了支持两种特性:一是Java的远程方法调用(RMI);二是Java Beans。

读书笔记——Java IO的更多相关文章

  1. 《深入了解java虚拟机》高效并发读书笔记——Java内存模型,线程,线程安全 与锁优化

    <深入了解java虚拟机>高效并发读书笔记--Java内存模型,线程,线程安全 与锁优化 本文主要参考<深入了解java虚拟机>高效并发章节 关于锁升级,偏向锁,轻量级锁参考& ...

  2. 【Think in java读书笔记】IO系统

    一.FIle类(处理文件目录问题) if else的另外一种写法 ,不加大括号也可以 import java.io.File; import java.io.FilenameFilter; impor ...

  3. [读书笔记]java核心技术

    ps:有时间好好整理下格式.从别的编辑器拷贝过来啥都没了. ~~~~~~~~~~~~~~· 2.java程序设计环境 JDK 开发java使用的软件: JRE 运行java使用的软件: SE 用于桌面 ...

  4. Java SE 8 for the Really Impatient读书笔记——Java 8 Lambda表达式

    1. lambda表达式的语法 lambda表达式是一种没有名字的函数,它拥有函数体和参数. lambda表达式的语法十分简单:参数->主体.通过->来分离参数和主体. 1.1 参数 la ...

  5. 学习笔记-java IO流总结 转载

    1.什么是IO Java中I/O操作主要是指使用Java进行输入,输出操作. Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列.Java的I/O流提供了读 ...

  6. [读书笔记]java中的volatile关键词

    以下内容大多来自周志明的<深入理解Java虚拟机>. 当一个变量被volatile修饰后,它将具备两种特性: 1. 保证此变量对所有线程的可见性,这里的“可见性”是指当一条线程修改了这个变 ...

  7. [读书笔记]Java之动态分派

    以下内容来自周志明的<深入理解Java虚拟机>. 前一篇说了静态分派和重载有关,现在的动态分派就和覆盖Override有关了. 先看代码: public class DynamicDisp ...

  8. [读书笔记]Java之静态分派

    以下内容来自周志明的<深入理解Java虚拟机>. 静态分派和重载有关. 先看代码: public static void main(String[] args) { SuperClass ...

  9. [读书笔记]java中的类加载器

    以下内容大多来自周志明的<深入理解Java虚拟机>. 类加载器是java的一项创新,也是java流行的重要原因之一,它最初是为了满足java applet的需求而开发出来. 什么是appl ...

随机推荐

  1. 老鸟需要知道的一些php系统类函数

    作为一个老手级别的php程序员,知道下面几个php系统级别的函数,不足为多吧!获取系统信息和调试程序的时候应该能用的上! PHP系统类函数 assert函数:检查assertion声明是否错误 ext ...

  2. android:onKeyDown

    android项目中的返回键有时处理不当,会是一个十分麻烦的问题. 在监听物理键时,可以用onKeyDown方法,Activity已经自己有KeyEvent.Callback这个接口了,因为项目有使用 ...

  3. tableView滚动的时候会 最后一行显示不完全的问题

    问题可能原因 1:tableView高度的设置不正确,应该是屏幕的高度减去上面的高度(包括状态栏以及navigationBar的高度).正确设置了tableView的高度之后,才可以正常滚动到最后一行 ...

  4. webservice接口调用存储过程返回失败

    poka.cashman.timer.service.impl.PdaOperateServiceImpl - Method Name: cashBoxOutOrIn; cbInfo:JN002015 ...

  5. hdu 1001 二叉树搜索

    Problem Description 判断两序列是否为同一二叉搜索树序列 Input 开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束.接下去一行是一个序 ...

  6. SAX,DOM,JAXP,JDOM,DOM4J比较

    dom,sax,jdom,dom4j的技术特点: 1: DOMDOM 是用与平台和语言无关的方式表示 XML 文档的官方 W3C 标准.DOM 是以层次结构组织的节点或信息片断的集合.这个层次结构允许 ...

  7. java 网络编程Socket编程

    Server.java import java.io.*; import java.net.*; public class Server { public static void main(Strin ...

  8. VirtualBox中CentOS通过Host-Only方式实现虚拟机主机互相访问、共享上网

    VirtualBox常用的网络配置如下: 连接方式 主机访问虚拟机 虚拟机访问主机 虚拟机访问虚拟机 虚拟机访问外网 说明 网络地址转换(NAT) 不支持 支持 不支持 支持 默认连接方式,虚拟IP, ...

  9. Telepro工具注册码

    Teleport Pro v1.54 注册码 Teleport Pro v1.54姓名(Name):3ddown.com序列号(Serial):161594593

  10. 【项目笔记】拿宽高前measure(widthMeasureSpec, heightMeasureSpec)的使用技巧

    我们知道获取宽高一般写法是: view.measure(0, 0); view.getMeasuredHeight(); 拿宽高前什么时候可以直接用measure(0, 0);而什么时候不能用meas ...