2

不同情境的流:

流的种类很多,针对不同的IO数据交换情景我们可以选择不同的流来完成任务。

我们在前面已经提到的几种流就有它们的使用情境:

1. FileInputStream和FileOutputStream

FileInputStream和FileOutputStream主要用于解决不限于纯文本的二进制文件的输入输出情境。同时,如果使用带有缓冲区的缓冲输入输出流的话会使得读写IO的效率更高,有助于更快地完成不限于纯文本的二进制文件的读写。

public class FilesTest {
    public static void main(String[] args) throws IOException {
        FileInputStream fileInputStream = new FileInputStream(new File("1.png"));
        BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
        FileOutputStream fileOutputStream = new FileOutputStream(new File("2.png"));
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
        byte[] buffer = new byte[1024];
        while(bufferedInputStream.read(buffer)!=-1){
            bufferedOutputStream.write(buffer);
        }
        bufferedInputStream.close();
        bufferedOutputStream.close();
        fileInputStream.close();
        fileOutputStream.close();
    }
}

2. FileReader和FileWriter

FileReader和FileWriter主要用于解决字符文本文件的读写,因为在这些流提供了很多有利于处理字符的方法来对字符进行丰富的处理。同样的,如果使用带有缓冲区的输入输出流同样可以提高IO读写效率。

public class FilesTest {
public static void main(String[] args) throws IOException {
        FileReader fileReader = new FileReader(new File("1.txt"));
        FileWriter fileWriter = new FileWriter(new File("2.txt"));
        BufferedReader bufferedReader = new BufferedReader(fileReader);
        BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
        String haveRead;
        while((haveRead=bufferedReader.readLine())!=null){
        bufferedWriter.write(haveRead);
        }
        bufferedReader.close();
        bufferedWriter.close();
        fileWriter.close();
        fileReader.close();
    }
}

3. ByteArrayInputStream和ByteArrayOutputStream

内存流的输入输出端不是IO文件而是内存中的对象,使用方法和IO流一样,一般使用内存流直接向流中注入数据再传到其他的IO文件中去或者把从IO文件中读取的数据注入到内存对象中去。

//创建与内存对象相关联的流,将内存对象中的数据写入到IO文件中去:

public class FilesTest {
public static void main(String[] args) throws IOException {
String temp = "abcd";

byte[] buffer = temp.getBytes();

ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(buffer);

FileOutputStream fileOutputStream = new FileOutputStream(new File("test.txt"));

byte[] swap = new byte[1024];

while(byteArrayInputStream.read(swap)!=-1){

fileOutputStream.write(swap);


}

byteArrayInputStream.close();

fileOutputStream.close();

    }
}

//创建与内存对象相关联的流,将IO对象中的数据写入到内存对象中去:

public class FilesTest {
public static void main(String[] args) throws IOException {
byte[] des = new byte[1024];

FileInputStream fileInputStream = new FileInputStream(new File("test.txt"));

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

byte[] buffer = new byte[1024];

while(fileInputStream.read(buffer)!=-1){

byteArrayOutputStream.write(buffer);


}

des = byteArrayOutputStream.toByteArray();

fileInputStream.close();

byteArrayOutputStream.close();

System.out.println(new String(des));

    }
}

4. System.in和System.out

作为非常重要的IO对象,标准输入输出System.in和System.out这一对对象同样可以建立起关联它们的流,这些流把标准输入输出设备中的数据作为源或目标,将这些数据和内存中的程序交互。(可以把标准输入输出想成一般的文件,标准输入就像是一个数据是即时写入的文件,而标准输出就像是一个数据是即时写出的文件)

public class FilesTest {
    public static void main(String[] args) throws IOException {
        byte[] des = new byte[1024];
        DataInputStream dataInputStream = new DataInputStream(System.in);
        dataInputStream.read(des);
        DataOutputStream dataOutputStream = new DataOutputStream(System.out);
        dataOutputStream.write(des);
        dataInputStream.close();
        dataOutputStream.close();
    }
}

流的转换

对于字节流和字符流也可以通过转换的方法来灵活使用,也就是构造字节流和字符流在同一个流对象链上就可以了,相当于字节流在直接和程序交互之前先将数据流到字符流里做一下处理。这个过程也可以使用专有的InputStreamReader和OutputStreamWriter来实现:这个过程将FileInputStream流里的数据按一种编码方式读入InputStreamReader,然后按另一种编码方式从OutputStreamWriter写入到FileOutputStream中这个过程实现了对字符编码的修改,是字符流的特征。

public class FilesTest {
    public static void main(String[] args) throws IOException {
        FileInputStream fileInputStream = new FileInputStream(new File("1.txt"));
        InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,"iso8859-1");
        FileOutputStream fileOutputStream = new FileOutputStream(new File("2.txt"));
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream,"utf-8");
        char[] buffer = new char[1024];
        while(inputStreamReader.read(buffer)!=-1){
            outputStreamWriter.write(buffer);
        }
        inputStreamReader.close();
        outputStreamWriter.close();
        fileInputStream.close();
        fileOutputStream.close();
    }
}

这个例子是对BufferReader进一步转换的工具类Scanner的使用,在底层使用BufferReader的Scanner可以在缓冲区对数据进行暂存并进一步进行处理,比如按符号划分:

public class FilesTest {
    public static void main(String[] args) {
        try (Scanner scanner = new Scanner(new BufferedReader(new FileReader("test.txt")));) {
            scanner.useDelimiter("[,|^]");
            while (scanner.hasNext()) {
                System.out.println(scanner.next());
            }
            System.out.println("Done!");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

JinhaoPlus
1.5k 声望92 粉丝

扎瓦程序员