Day34---学习Java第二弹

2021-08-13

Java输入输出流

5. FileInputStream流和FileOutputStream的应用

利用程序将文件file1.txt 拷贝到file2.txt中。
import java.io.File;
import java.io.IOException;
import java.io.FileOutputStream;
import java.io.FileInputStream;
 
public class TestFile {
    public static void main(String args[]) throws IOException {
        try {
            File inFile = new File("copy.java");
            File outFile = new File("copy2.java");
            FileInputStream finS = new FileInputStream(inFile);
            FileOutputStream foutS = new FileOutputStream(outFile);
            int c;
            while ((c = finS.read()) != -1) {
                foutS.write(c);
            }
            finS.close();
            foutS.close();
        } catch (IOException e) {
            System.err.println("FileStreamsTest: " + e);
        }
    }
 
}

 

 

6. 缓冲输入输出流 BufferedInputStream/ BufferedOutputStream

Day34---学习Java第二弹

 

 

计算机访问外部设备非常耗时。访问外存的频率越高,造成CPU闲置的概率就越大。为了减少访问外存的次数,

应该在一次对外设的访问中,读写更多的数据。为此,除了程序和流节点间交换数据必需的读写机制外,

还应该增加缓冲机制。缓冲流就是每一个数据流分配一个缓冲区,一个缓冲区就是一个临时存储数据的内存。这样可以减少访问硬盘的次数,提高传输效率。

 

BufferedInputStream: BufferedInputStream比FileInputStream多了一个缓冲区。它提供了一个缓冲数组,

每次调用read方法的时候,它首先尝试从缓冲区里读取数据,若读取失败(缓冲区无可读数据),则选择从物理数据源

(譬如文件)读取新数据(这里会尝试尽可能读取多的字节)放入到缓冲区中,最后再将缓冲区中的内容部分或全部返回给用户.

由于从缓冲区里读取数据远比直接从物理数据源(譬如文件)读取速度快。BufferedInputStream的默认缓冲区大小是8192字节。

当每次读取的数据量很小时,FileInputStream每次都是从硬盘读入,而BufferedInputStream大部分是从缓冲区读入。

读取内存速度比读取硬盘速度快得多,因此BufferedInputStream效率高。

 

例如:BUFFER_SIZE < 8192时候,BufferedInputStream性能是很高。

 

BufferedInputStream bufferedInput = new BufferedInputStream(new FileInputStream(fileA));
byte[] buffer = new byte[BUFFER_SIZE];
int len;
while ((len = bufferedInput.read(buffer)) > 0){
System.out.println(new String(buffer, 0, len));
}
BUFFER_SIZE > 8192时候, FileInputStream和BufferedInputStream两者效率就没有明显差别了。

BufferedOutputStream :执行wirte时先写入缓冲区,待缓冲区写满后,系统再写入输出设备。

 

1)将文件读入内存:

将BufferedInputStream与FileInputStream相接

FileInputStream in = new FileInputStream( “file1.txt ” );

BufferedInputStream bin = new BufferedInputStream( in);

 

 

2)将内存写入文件:

将BufferedOutputStream 与 FileOutputStream相接:

String fileB = "/Users/huangguisu/b.txt";
FileOutputStream out = new FileOutputStream(fileB);
BufferedOutputStream bOut = new BufferedOutputStream(out);
byte[] buffer = {0x1,0x2,0x3};
bOut.write(buffer);
bOut.flush();
bOut.close();


3)键盘输入流读到内存
将 BufferedReader 与 标准的数据流 相接
InputStreamReader sin = new InputStreamReader ( System.in) ;
BufferedReader bin = new BufferedReader( sin);

import java.io.*;
 
public class ReadWriteToFile {
    public static void main(String args[]) throws IOException {
        InputStreamReader sin = new InputStreamReader(System.in);
        BufferedReader bin = new BufferedReader(sin);
        FileWriter out = new FileWriter("myfile.txt");
        BufferedWriter bout = new BufferedWriter(out);
        String s;
        while ((s = bin.readLine()).length() > 0) {
            bout.write(s, 0, s.length());
        }
 
    }
}

程序说明:
从键盘读入字符,并写入到文件中BufferedReader类的方法:String readLine()
作用:读一行字符串,以回车符为结束。
BufferedWriter类的方法:bout.write(String s,offset,len)
作用:从缓冲区将字符串s从offset开始,len长度的字符串写到某处。

 

八. 字符流Writer/Reader
Java中字符是采用Unicode标准,一个字符是16位,即一个字符使用两个字节来表示。为此,JAVA中引入了处理字符的流。

1. Reader抽象类
用于读取字符流的抽象类。子类必须实现的方法只有 read(char[], int, int) 和 close()。但是,

多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。

Day34---学习Java第二弹

 

 

1) FileReader :与FileInputStream对应
主要用来读取字符文件,使用缺省的字符编码,有三种构造函数:
   (1)将文件名作为字符串 :FileReader f = new FileReader(“c:/temp.txt”);
   (2)构造函数将File对象作为其参数。
   File f=new file(“c:/temp.txt”);
   FileReader f1=new FileReader(f);
   (3) 构造函数将FileDescriptor对象作为参数
   FileDescriptor() fd = new FileDescriptor()
   FileReader f2=new FileReader(fd);


(1) 用指定字符数组作为参数:CharArrayReader(char[])


(2) 将字符数组作为输入流:CharArrayReader(char[], int, int)
  读取字符串,构造函数如下: public StringReader(String s);


2) CharArrayReader:与ByteArrayInputStream对应


3) StringReader : 与StringBufferInputStream对应


4) InputStreamReader
从输入流读取字节,在将它们转换成字符:Public inputstreamReader(inputstream is);


5) FilterReader: 允许过滤字符流
protected filterReader(Reader r);


6) BufferReader :接受Reader对象作为参数,并对其添加字符缓冲器,使用readline()方法可以读取一行。
 Public BufferReader(Reader r);

主要方法:

(1) public int read() throws IOException; //读取一个字符,返回值为读取的字符

  (2) public int read(char cbuf[]) throws IOException; /*读取一系列字符到数组cbuf[]中,返回值为实际读取的字符的数量*/
  (3) public abstract int read(char cbuf[],int off,int len) throws IOException;
  /*读取len个字符,从数组cbuf[]的下标off处开始存放,返回值为实际读取的字符数量,该方法必须由子类实现*/

 

 

2. Writer抽象类
写入字符流的抽象类。子类必须实现的方法仅有 write(char[], int, int)、flush() 和 close()。但是,

多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。 其子类如下:

1) FileWrite: 与FileOutputStream对应
  将字符类型数据写入文件,使用缺省字符编码和缓冲器大小。
  Public FileWrite(file f);


2) chararrayWrite:与ByteArrayOutputStream对应 ,将字符缓冲器用作输出。
   Public CharArrayWrite();


3) PrintWrite:生成格式化输出
   public PrintWriter(outputstream os);


4) filterWriter:用于写入过滤字符流
   protected FilterWriter(Writer w);


5) PipedWriter:与PipedOutputStream对应

6) StringWriter:无与之对应的以字节为导向的stream

主要方法:

  (1) public void write(int c) throws IOException; //将整型值c的低16位写入输出流
  (2) public void write(char cbuf[]) throws IOException; //将字符数组cbuf[]写入输出流
  (3) public abstract void write(char cbuf[],int off,int len) throws IOException; //将字符数组cbuf[]中的从索引为off的位置处开始的len个字符写入输出流
  (4) public void write(String str) throws IOException; //将字符串str中的字符写入输出流
  (5) public void write(String str,int off,int len) throws IOException; //将字符串str 中从索引off开始处的len个字符写入输出流
  (6) flush( ) //刷空输出流,并输出所有被缓存的字节。
  (7)close() 关闭流 public abstract void close() throws IOException

 

3 .InputStream与Reader差别 OutputStream与Writer差别

InputStream和OutputStream类处理的是字节流,数据流中的最小单位是字节(8个bit)
Reader与Writer处理的是字符流,在处理字符流时涉及了字符编码的转换问题

import java.io.*;
public class EncodeTest {
    private static void readBuff(byte [] buff) throws IOException {
       ByteArrayInputStream in =new ByteArrayInputStream(buff);
        int data;
        while((data=in.read())!=-1)   System.out.print(data+"  ");
        System.out.println();     in.close();     }
 
   public static void main(String args[]) throws IOException {
       System.out.println("内存中采用unicode字符编码:" );
       char   c='好';
       int lowBit=c&0xFF;     int highBit=(c&0xFF00)>>8;
       System.out.println(""+lowBit+"   "+highBit);
       String s="好";
       System.out.println("本地操作系统默认字符编码:");
       readBuff(s.getBytes());
       System.out.println("采用GBK字符编码:");
       readBuff(s.getBytes("GBK"));
       System.out.println("采用UTF-8字符编码:");      
       readBuff(s.getBytes("UTF-8"));      }
}

Reader类能够将输入流中采用其他编码类型的字符转换为Unicode字符,然后在内存中为其分配内存

Writer类能够将内存中的Unicode字符转换为其他编码类型的字符,再写到输出流中。

 

 

4、BufferedInputStream 和BufferedReader区别
首先虽然都作为一个包装类,但是BufferedReader针对字符流,BufferedInputStream针对字节流

 

BufferedInputStream在实现的时候是在自身read方法中提供缓存,是一次取1024或更多字节然后再慢慢读,一个个的返回,它并没有实现读一行的方法

 

BufferedReader在实现时通过提供一个readLine方法,使用数组或者stringBuilder存储一行数据,并一次性返回


 

 ---------------------------------------------------------------------------------------------------------------------------------

下周继续

上一篇:TCP


下一篇:IO之字节流