Java IO(2)阻塞式输入输出(BIO)

  在上文中

1 File file = new File("/Users/yulinfeng/Documents/Coding/Idea/maveneg/src/main/java/bio/test.json"); 2 InputStream in = new FileInputStream(file); 3 byte[] b = new byte[64]; 4 in.read(b); 5 System.out.println(new String(b));
复制代码

  这段代码是读取本地文件获取文件中的信息,其中read方法关键,FileInputStream中一共有3个read重载方法:

  1.  public int read() //返回读取的字节,FileInputStream是按照字节流的方式读取,使用该方法将一次读取一个字节并返回该字节。该方法中会调用private native int read0()本地方法。
  2.  public int read(byte b[]) //将读取的字节全部放到字节数组b中,这个字节数组b是我们提前定义好的,用于存放读取文件的字节表示,返回一共读取的字(1个字母表示1个字,1中文通常则是3个字)。该方法会调用private native int readBytes(byte b[], int off, int len)本地方法。
  3. read(byte b[], int off, int len) //读取数据的开始处以及待存放字节数组的长度,基本同上,返回一共读取的字符(1个字母表示1个字符,1中文通常占用3个字节也就是3个字符)。该方法会调用private native int readBytes(byte b[], int off, int len)本地方法。

  这基本上就构成了通过FileInputStream字节流读取文件的API,到了这里应该会有一个疑问,那就是读取出来的字节放到我们定义的字节数组中,而这个数组有需要在初始化时给定大小,那此时是如何知道待读取的文件大小呢?上面定义的64个字节大小的数组,如果待读取的文件有128字节甚至更大呢?就好像上面的例子,如果之定义1个字节大小,那么最后只会输出文件中的第1个字节。但如果定义64个字节大小的字节数组,那又显得比较浪费。

输出流(OutputStream)

  同样是站在程序的角度,写入文件的操作称为输出。和InputStream类比,它也有许多实现类,在这里不再一一举出,着重来看FileOutputStream输出到本地文件的类。如果文件不存在则创建。

复制代码
1 OutputStream out = new FileOutputStream("/Users/yulinfeng/Documents/Coding/Idea/maveneg/src/main/java/bio/test.json"); 2 String str = "this is data"; 3 out.write(str.getBytes());    // 由于是以字节流的方式输出,自然也是需要将输出的内容转换为字节。
复制代码

  FileOutputStream类的构造方法一共有5个:主要是分为“文件地址”、“是否以追加方式写入”、“文件描述符”。 

  1.  OutputStream out = new FileOutputStream(“/Users/yulinfeng/Documents/Coding/Idea/maveneg/src/main/java/bio/test.json”); //直接传递文件路径字符串,在构造方法中会将其构造为一个File对象,如果文件不存在则会新建文件,默认将覆盖文件的内容进行写入。因为它实际上是调用FileInputStream(File, boolean)构造方法。
  2.  OutputStream out = new FileOutputStream(new File(“/Users/yulinfeng/Documents/Coding/Idea/maveneg/src/main/java/bio/test.json””)) //传递File对象,默认将覆盖文件的内容进行写入。实际还是调用FileInputStream(File, boolean)。
  3.  OutputStream out = new FileOutputStream(“/Users/yulinfeng/Documents/Coding/Idea/maveneg/src/main/java/bio/test.json”, true); //第一个参数如第一点所述,第二个参数则表示以追加的方式写入。
  4.  OutputStream out = new FileOutputStream(new File(“/Users/yulinfeng/Documents/Coding/Idea/maveneg/src/main/java/bio/test.json””), true) //向上参考 
  5.  OutputStream out = new FileOutputStream (new FileDescriptor()); //第三个构造方法传递的是“文件描述符”对象,不需要过多的关注这个构造方法,因为实在能用的地方不多。

  对于文件输出的核心API是write方法,对应文件输入的read方法。既然read能单个读取,那么write也有单个写入,其重载方法一共有3个。 

  1.  public void write(int b); //写入单个字节,该方法会调用private native write(b, append)这个方法是私有且本地的,至于第二个append的参数则是表示是否追加写入文件,这里的参数是在构造方法中定义的,默认不追加写入而是以覆盖的方式写入。
  2.  public void write(byte b[]); //写入字节,这里传递转换后的字节数组,通常我们是需要写入一个字符串,而这里调用String.valueOf将其转换为字符数组。此方法会调用private native void writeBytes(byte b[], int off, int len, boolean append),和写入的类似,第二个参数表示字节数组从哪个地方开始写入,len表示写入多少,最后一个还是表示是否是追加写入。
  3.  public void write(byte b[], int off, int len); //分析见上 这是对OutputStream的其中一个实现类做的简要讲述,API也较为简单,类比很好掌握。

字符流(Reader、Writer)

输入流(Reader)

  对于字符流的文件读取方式可以不用像字节流那样,读取出来是一个字节,想要输出显示这个字节则需要将这个字节转换为字符。字符流读取出来的文件则直接就是字符,不需要再重新转化。Reader和InputStream类似,也是一个抽象类,它也有不少的实现,其主要实现如下。

  1.  CharArrayReader
  2.  StringReader
  3.  InputStreamReader——这个类略有不同,这个类是字节流和字符流之间的桥梁,它能将字节流转换为字符流,相对比于“FileInputStream”,字节流的本地文件读取实际上是InputStreamReader的子类——FileReader
  4.  PipedReader
  5.  FilterReader

  对比字符流的FileInputStream类,此处使用FileReader。和FileInputStream类似它同样有3个构造方法:

  1.  Reader reader = new FileReader(/Users/yulinfeng/Documents/Coding/Idea/maveneg/src/main/java/bio/test.json”); //直接传递文件路径字符串,在这个构造函数中会为路径中的文件创建File对象。 
  2.  Reader reader = new FileReader(new File(“/Users/yulinfeng/Documents/Coding/Idea/maveneg/src/main/java/bio/test.json””)); //传递File类型的对象,也就是我们自己为路径中的文件构造为File文件类型。 
  3.  Reader reader = new FileReader(new FileDescriptor()); //第三个构造方法传递的是“文件描述符”对象,通过文件描述符来定位文件,如果比较了解Linux和C的话应该是对“文件描述符”这个概念有所耳闻,在许多C源码中就时常出现“fd”这个变量,其表示的就是文件描述符,就是用于定位文件,暂时对它可以忽略。

  可以看到它的API操作几乎和FileInputStream如出一辙,唯一不同的是,它定义的是字符数组而不是字节数组。

复制代码
1 Reader reader = new FileReader("/Users/yulinfeng/Documents/Coding/Idea/maveneg/src/main/java/bio/test.json"); 
                        
关键字:
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信