IO流之字节流、字符流

InputStream

  • InputStream抽象类是所有字节输入流类的超类,使用此类的方法可以从流中读取一个或一批字节,具体方法见API;注意:使用mark()和reset()方法之前,需要判断该文件是否支持这两个方法;

  • InputStream常用的子类:

    • FileInputStream:从文件中读取数据

    • ByteArrayInpuStream类:将字节数组转换为字节输入流,从中读取字节

    • PipedInputStream类:连接到一个PipedOutputStream(管道输出流)

    • BufferedInputStream:缓冲字节输入流(也可操作文件)

    • ObjectInputStream:对象字节输入流


FileInputStream

表示从文件系统的某个文件中获取输入字节。创建该类对象时,如果找不到指定的文件将会抛出FileNotFoundException异常,该异常必须捕获或声明抛出;

捕获异常快捷键:ctrl + alt + t

  • 构造方法

    1. FileInputStream(File file);

    2. FileInputStream(FileDescriptor fbObj);

    3. FileInputStream(String name);name为文件路径

  • 常用方法

    1. public int read() throws IOException:从该输入流读取一个字节的数据。 读取完毕返回-1;正常读取返回字符对应的char值

    2. public int read(byte[] b) throws IOException:从该输入流读取最多b.length()字节的数据,存储到b中。 读取完毕返回-1;正常读取,返回读取到的字节数

//使用read()读取文件
String filePath = "e:\\hello.txt";
int readData = 0;//用于接收字符的char值
FileInputStream fileInputStream = null;
try{
//创建 FileInputStream 对象,用于读取文件,实参为文件路径
fileInputStream = new FileInputStream(filePath);
//read()从该输入流读取一个字节的数据。
//如果读取完毕,返回-1
while ((readData = fileInputStream.read()) != -1){
//System.out.print(readData);
System.out.print((char)readData);
}
}catch(IOException e){
e.printStackTrace();
}finally {
//关闭文件流,释放资源
try {//捕获close的异常
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}

//使用read(byte[] b)读取文件
String filePath = "e:\\hello.txt";
int readData = 0;//用于接收读取字符的数量
byte[] buffer = new byte[8];//一次读取8个字节
FileInputStream fileInputStream = null;//try外声明,以便捕获关闭流时抛出异常
try{
//创建 FileInputStream 对象,用于读取文件
fileInputStream = new FileInputStream(filePath);//创建
//从该输入流读取最多b.length字节的数据。
//如果读取完毕,返回-1
//正常读取,返回读取到的字节数
//每次读取,对byte[] buffer从0位开始覆盖
while ((readData = fileInputStream.read(buffer)) != -1){
System.out.print(readData);
//字符数组从0-读取的个数转成字符串显示
System.out.print(new String(buffer, 0, readData));
}
}catch(IOException e){
e.printStackTrace();
}finally {
//关闭文件流,释放资源
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}

OutputStream

  • OutputStream类是所有字节输出流的父类,使用此类的方法可以从流中读取一个或一批字节,具体方法见API;

  • 其常用子类有:

    • FileOutputStream类:向文件中写入数据

    • ByteArrayOutpuStream类:向内存缓冲区的字节数组中写数据

    • PipedOutputStream类:连接到一个PipedInputStream(管道输入流)

    • ObjectOutputStream:将对象序列化


FileOutputStream

同一个流对象中,使用多种写入方法,不会覆盖前面方法写入的字符,但下一个流对象会覆盖原文件的内容,设置true后,则是文件拼接,而不是文件覆盖

  • 构造方法

    1. FileOutputStream(File file);创建文件输出流以写入由指定的 File对象表示的文件。默认覆盖原文件

    2. FileOutputStream(File file, boolean append);创建文件输出流以写入由指定的 File对象表示的文件;可以指定append为true或false,以指定文件是在原文件的基础上拼接还是覆盖;

    3. 详见API

  • 常用方法

    1. write(int b) ;写入char值为b的字符,或者字符b;

    2. write(byte [] b);将 字节数组b中的每个字节写入此文件输出流;

    3. write(byte[] b, int off, int len);从字符数组b中的off位置开始,写入len个字符

    4. 详见API

往文件中写入汉字,通过字符串转成字符数组写入时,需将每个汉字的全部字符写入(UTP-8中汉字占3个字符)

多次写入需要换行时,可以写入换行符String str = "\r\n";

说明

  1. 构造方法中指定目标文件时,目标文件可以不存在

  2. 目标文件的名称及后缀任意,可以使用记事本等工具打开并浏览

  3. 目标文件所在目录必须存在,否则抛出异常:java.io.FileNotFoundException

  4. 目标文件的名称不能是已存在的目录,否则抛出异常:java.io.FileNotFoundException

		//创建FileOutputStream对象,可选择默认,true,false(默认)
String filePath = "e:\\a.txt";//创建文件路径名称
FileOutputStream fileOutputStream = null;//声明
try {//捕获异常
fileOutputStream = new FileOutputStream(filePath,true);//创建
//写入一个字节
fileOutputStream.write('a');
//写入字符串
String str = "hello,world";
//str.getBytes()将str转为字符数组
fileOutputStream.write(str.getBytes());
fileOutputStream.write(str.getBytes(),0,4);

} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}

文件拷贝

  • 完成文件拷贝,将e:\image-20220807162602134.jpg拷贝到d:\

  • 1、创建输入流,将文件读取到程序

  • 2、创建输出流,将程序中读取到的输出到目标文件

  • 3、边读边写,循环运行“输入-->输出”,以完成文件拷贝(避免文件过大,一次性输入输出)

String filePathOld = "e:\\\\image-20220807162602134.jpg";
String filePathNew = "d:\\xxx.jpg";
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;

try {
fileInputStream = new FileInputStream(filePathOld);
fileOutputStream = new FileOutputStream(filePathNew);
//定义一个字节数组
byte [] buff = new byte[1024];//一次读取1024个字符
int readLen = 0;//接收读取的字符个数
while ((readLen = fileInputStream.read(buff)) != -1){//无限循环读取,直至完毕
//读取到后,写入文件
fileOutputStream.write(buff,0,readLen);//多次写入
}
System.out.println("拷贝成功");
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if (fileInputStream != null){
fileInputStream.close();//关闭
}if (fileOutputStream != null){
fileOutputStream.close();//关闭
}
} catch (IOException e) {
e.printStackTrace();
}
}

Reader

尽管Java中字节流几乎可以直接或间接地处理任何类型的输入/输出操作,但利用它却不能直接操作16位的Unicode字符,这就要用到字符流。

  • Reader类是所有字符流输入流的父类,该类定义了许多方法,这些方法对所有子类都是有效的

  • 常用子类:

    • CharArrayReader类:将字符数组转换为字符输入流,从中读取字符

    • StringReader类:将字符串转换为字符输入流,从中读取字符

    • PipedReader类:连接到一个PipedWriter

    • InputStreamReader类:将字节输入流转换为字符输入流,可以指定字符编码

  • 常用方法

    • int read():返回读取的一个字符的值对应的数字;读取完毕,返回-1

    • int read(char [] b):读取若干个字符,保存到字符数组b中,返回读取的字符个数;读取完毕返回-1

    • int read(char [] b,off,len):读取len个字符,从字符数组下标off处开始保存;返回读取的字符个数,读取完毕,返回-1

FileReader

  • 相关方法

    1. new FileReader(File/String):构造器

    2. read:每次读取单个字符,返回该字符,读取结束返回-1;

    3. read( char []):批量读取多个字符到数组,返回读取的字符数,读取完毕返回-1;

  • 相关API

    1. new String (char []):将char[]转换成String

    2. new String (char [] ,off,len):将char[]的指定部分转换成String

		String filePath = "e:\\a.txt";
FileReader fileReader = null;
int data = 0;
try {
fileReader = new FileReader(filePath);
//循环读取,使用read,返回读取字符对应的数字
while ((data = fileReader.read()) !=-1){
System.out.print((char)data);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
		String filePath = "e:\\a.txt";
FileReader fileReader = null;
int data = 0;
char [] buff = new char[8];
try {
fileReader = new FileReader(filePath);
//循环读取,使用read(buff),返回读取的字符个数
while ((data = fileReader.read(buff)) !=-1){
System.out.println(new String(buff,0,data));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}

 

Writer

  • Writer类是所有字符流输出流的父类,该类定义了许多方法,这些方法对所有子类都是有效的

  • 常用子类:

    • CharArrayWriter类:向内存缓冲区的字符数组写数据

    • StringWriter类:向内存缓冲区的字符串(StringBuffer)写数据

    • BufferedWriter类:为其他字符输出流提供写缓冲区

    • PipedWriter类:连接到一个PipedReader

    • OutputStreamReader类:将字节输出流转换为字符输出流,可以指定字符编码

  • 常用方法:

    • writer():

    • append():

    • 详见API

注意:Writer类所有的方法在出错的情况下都会引发 IOException 异常。关闭一个流后,再对其进行任何操作都会产生错误。


FileWriter

  • 相关方法

    1. new FileWriter(File/Strign):覆盖模式,数据写入文件,会覆盖原文件内容

    2. new FileWriter(File/String,true):追加模式,在原文件基础上进行续写

    3. writer(int b):写入单个字符

    4. writer(char []):写入指定数组

    5. writer(char [],off,len):写入指定数组的指定部分

    6. writer(string):写入整个字符串

    7. writer(string,off,len):写入字符串的指定部分

  • 相关API

    1. String类:toCharArray:将String转换成char[]

注意:FileWriter使用后,必须关闭(close)或刷新(flush),否则写入不到指定的文件!

        String filePath = "e:\\xxt.txt";
       //先创建fileWriter
       FileWriter fileWriter = null;//声明
       char  ch = 'H';//
       char [] ch_ = {'a','b','c','e'};
       String str = "风雨过后,必见彩虹";
       try {
           fileWriter = new FileWriter(filePath);//创建
           fileWriter.write(ch);//写入字符
           fileWriter.write(ch_);//写入字符数组
           fileWriter.write(ch_,1,2);//写入字符数组的指定部分
           fileWriter.write(str);//写入字符串
           fileWriter.write(str,1,3);//写入字符串的指定部分
      } catch (IOException e) {
           e.printStackTrace();
      } finally {
           try {
               fileWriter.close();
          } catch (IOException e) {
               e.printStackTrace();
          }
      }

节点流

  • 节点流可以从数据源读写数据;如:FileReader、FileWriter


  • 节点流和处理流的区别和联系:

    1. 节点流是底层流/低级流,直接跟数据源相接;

    2. 处理流包装节点流,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入输出;

    3. 处理流对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相接;

      修饰器设计模式,详见io.bufferfile包简单模拟设计模式

  • 处理流的功能主要体现在以下两个方面

    1. 性能的提高:主要以增加缓冲的方式来提高输入输出的效率;

    2. 操作的便捷:处理流提高了一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便;

posted @ 2022-08-23 09:20  许多多被注册了  阅读(25)  评论(0编辑  收藏  举报