当前位置:天才代写 > tutorial > JAVA 教程 > Java编程那些事儿92——IO利用留意问题

Java编程那些事儿92——IO利用留意问题

2017-11-12 08:00 星期日 所属: JAVA 教程 浏览:298

副标题#e#

11.3.4 留意问题

上面先容了IO类的根基利用,熟悉了实体流和装饰流的根基利用,可是在IO类实际利用时,照旧会碰着一系列的问题,下面先容一些大概会常常碰着的问题。

11.3.4.1 类的选择

对付初次打仗IO技能的初学者来说,IO类体系博大博识,类的数量较量复杂,在实际利用时常常会无所适从,不知道该利用那些类举办编程,下面先容一下关于IO类选择的一些能力。

选择类的第一步是选择符合的实体流。

选择实体流时第一步是凭据毗连的数据源种类举办选择,譬喻读写文件应该利用文件流,如FileInputStream/FileOutputStream、FileReader/FileWriter,读写字节数组应该利用字节数组流等,如ByteArrayInputStream/ByteArrayOutputStream。

选择实体流时第二步是选择符合偏向的流。譬喻举办读操纵时应该利用输入流,举办写操纵时应该利用输出流。

选择实体流时第三步是选择字节约或字符流。除了读写二进制文件,或字节约中没有对应的流时,一般都优先选择字符流。

颠末以上步调今后,就可以选择到符合的实体流了。下面说一下装饰流的选择问题。

在选择IO类时,实体流是必须的,装饰流是可选的。别的在选择流时实体流只能选择一个,而装饰流可以选择多个。

选择装饰流时第一步是选择切合要求成果的流。譬喻需要缓冲流的话选择BufferedReader/BufferedWriter等,有些时候也大概只是为了利用某个装饰流内部提供的要领。

选择装饰流时第二步是选择符合偏向的流,这个和实体流选择中的第二步一致。

当选择了多个装饰流今后,可以利用流之间的多层嵌套实现要求的成果,流的嵌套之间没有顺序。

11.3.4.2  非依次读取流数据

由于IO类设计的特点,在实际读取时,只能依次读取流中的数据,并且在凡是环境下,已经读取过的数据无法再举办读取。假如需要反复读取流中某段数据时,一般的做法是将从流中读取的数据利用数组存储起来,然后按照需要读取数组中的内容即可,可是有些时候,照旧有一些非凡的环境的,IO类对付这些都举办了支持。

1、中断性的读取流中的数据

对付某些非凡名目标文件,譬喻字体文件等,在实际读取数据时不需要顺序举办读取,而只需要按照内容的位置举办读取。这样可以利用流中的skip要领实现。譬喻:

int n = fis.skip(100);

该行代码的浸染是,以流fis当前位置为基本,当前位置可以是流中的任何位置,向后跳过100个单元(字节约单元为字节,字符流单元是字符),假如再利用read要领继承读取,就是读取跳跃今后新位置的内容,也就相当于跳过了100个单元的内容。

而实际在利用时,实际真正跳过的单元数量作为skip要领的返回值返回。


#p#副标题#e#

2、反复读取流中某段数据

当必需反复读取流中同一段数据时,假如对应的流支持mark(标志)的话,则可以反复读取同一段数据。

下面以反复读取节制台输入流System.in为例子,来先容mark的利用,示例代码如下:

import java.io.*;
/**
* mark利用示例
*/
public class MarkUseDemo {
 public static void main(String[] args) {
  byte[] b = new byte[1024];
  try{
   //读取数据
   int data = System.in.read();
   //输出第一个字节的数据
   System.out.println("第一个字节:" + data);
   //判定该流是否支持mark
   if(System.in.markSupported()){
    //影象当前位置,可以从当前位置
    //向后最多读取100个字节
    System.in.mark(100);
    //读取数据
    int n = System.in.read(b);
    //输出读取到的内容
    System.out.print("第一次读取到的内容:");
    for(int i = 0;i < n;i++){
     System.out.print(b[i] + " ");
    }
    System.out.println();
    //回到标志位置
    System.in.reset();
    //反复读取标志位置今后的内容
    n = System.in.read(b);
    //输出读取到的内容
    System.out.print("第二次读取到的内容:");
    for(int i = 0;i < n;i++){
     System.out.print(b[i] + " ");
    }
    System.out.println();
   }
  }catch(Exception e){
    e.printStackTrace();
  }
 }
}

在该示例中,首先挪用System.in流中的read要领,读取流中的第一个字节,并把读取到的数据赋值给data,然后将读取到的第一个字节的数据输出出来。

然后挪用System.in流中的markSupported判定该流是否支持mark成果,假如支持的话则markSupported要领将返回true。

#p#分页标题#e#

假如流System.in支持mark,则标志当前位置,并答允从当前位置开始最多读取后续100个字节的数据,其实IO类内部的只读取这些数据,而不真正从流中将这些数据删除。

后续继承读取流中的数据,假如读取的数据高出100个字节,则mark标志失效,并把读取到的有效数据输出到节制台。

假如需要从标志位置反复读取已经读取过的数据,则只需要挪用流工具中的reset要领重置流的位置,使流可以回到mark的位置,假如继承读取的话,则从该位置开始可以向后读取。这样就可以从mark的位置开始,再次读取后续的数据了。

譬喻在节制台输入123456789,则该措施的执行功效是:

第一个字节:49

第一次读取到的内容:50 51 52 53 54 55 56 57 13 10

第二次读取到的内容:50 51 52 53 54 55 56 57 13 10

个中输入的第一个字节是1,读取时该字符的编码是49,尔后续的内容就是流的布局,个中流末端的13和10是在输入时,添加的回车和换行字符。

11.3.4.3 中文问题

由于JDK设计时,对付国际化支持较量好,所以JDK在实际实现时支持许多的字符集,这样在举办特定字符集的处理惩罚时就需要出格小心了。

其实在举办中文处理惩罚时,只需要留意一个原则就可以了,这个原则就是将中文字符转换为byte数组时利用的字符集,需要和把byte数组转换为中文字符串时的字符集保持一致,这样就不会呈现中文问题了。

虽然,假如不想手动实现字符串和byte数组的转换,可以利用DataInputStream和DataOutputStream中的readUTF和writeUTF实现读写字符串。

11.4 总结

关于IO类的利用,还需要在实际开拓进程中多举办利用,从而更深入的体会IO类设计的初志,并把握IO类的利用。

别的,IO类是Java中举办网络编程的基本,所以熟悉IO类的利用也是进修网络编程必需的一个基本。

 

    关键字:

天才代写-代写联系方式