Java IO流

1, File类

1.1 File类定义
  • File类主要是JAVA为文件这块的操作(如删除、新增等)而设计的相关类
  • File类的包名是java.io,其实现了Serializable, Comparable两大接口以便于其对象可序列化和比较
1.2 File类方法

构造方法:

File(URI uri)通过将给定的 file:URI转换为抽象路径名来创建新的 File实例。
File(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
File(String parent, String child) 从父路径名字符串和子路径名字符串创建新的 File实例。
File(URI uri) 通过将给定的 file: URI转换为抽象路径名来创建新的 File实例。

所有方法:

booleancanExecute() 测试应用程序是否可以执行此抽象路径名表示的文件。
booleancanRead() 测试应用程序是否可以读取由此抽象路径名表示的文件。
booleancanWrite() 测试应用程序是否可以修改由此抽象路径名表示的文件。
intcompareTo(File pathname) 比较两个抽象的路径名字典。
booleancreateNewFile() 当且仅当具有该名称的文件尚不存在时,原子地创建一个由该抽象路径名命名的新的空文件。
static FilecreateTempFile(String prefix, String suffix) 在默认临时文件目录中创建一个空文件,使用给定的前缀和后缀生成其名称。
static FilecreateTempFile(String prefix, String suffix, File directory) 在指定的目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。
booleandelete() 删除由此抽象路径名表示的文件或目录。
voiddeleteOnExit() 请求在虚拟机终止时删除由此抽象路径名表示的文件或目录。
booleanequals(Object obj) 测试此抽象路径名与给定对象的相等性。
booleanexists() 测试此抽象路径名表示的文件或目录是否存在。
FilegetAbsoluteFile() 返回此抽象路径名的绝对形式。
StringgetAbsolutePath() 返回此抽象路径名的绝对路径名字符串。
FilegetCanonicalFile() 返回此抽象路径名的规范形式。
StringgetCanonicalPath() 返回此抽象路径名的规范路径名字符串。
longgetFreeSpace() 返回分区未分配的字节数 named此抽象路径名。
StringgetName() 返回由此抽象路径名表示的文件或目录的名称。
StringgetParent() 返回此抽象路径名的父 null的路径名字符串,如果此路径名未命名为父目录,则返回null。
FilegetParentFile() 返回此抽象路径名的父,或抽象路径名 null如果此路径名没有指定父目录。
StringgetPath() 将此抽象路径名转换为路径名字符串。
longgetTotalSpace() 通过此抽象路径名返回分区 named的大小。
longgetUsableSpace() 返回上的分区提供给该虚拟机的字节数 named此抽象路径名。
inthashCode() 计算此抽象路径名的哈希码。
booleanisAbsolute() 测试这个抽象路径名是否是绝对的。
booleanisDirectory() 测试此抽象路径名表示的文件是否为目录。
booleanisFile() 测试此抽象路径名表示的文件是否为普通文件。
booleanisHidden() 测试此抽象路径名命名的文件是否为隐藏文件。
longlastModified() 返回此抽象路径名表示的文件上次修改的时间。
longlength() 返回由此抽象路径名表示的文件的长度。
String[]list() 返回一个字符串数组,命名由此抽象路径名表示的目录中的文件和目录。
String[]list(FilenameFilter filter) 返回一个字符串数组,命名由此抽象路径名表示的目录中满足指定过滤器的文件和目录。
File[]listFiles() 返回一个抽象路径名数组,表示由该抽象路径名表示的目录中的文件。
File[]listFiles(FileFilter filter) 返回一个抽象路径名数组,表示由此抽象路径名表示的满足指定过滤器的目录中的文件和目录。
File[]listFiles(FilenameFilter filter) 返回一个抽象路径名数组,表示由此抽象路径名表示的满足指定过滤器的目录中的文件和目录。
static File[]listRoots() 列出可用的文件系统根。
booleanmkdir() 创建由此抽象路径名命名的目录。
booleanmkdirs() 创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录。
booleanrenameTo(File dest) 重命名由此抽象路径名表示的文件。
booleansetExecutable(boolean executable) 为此抽象路径名设置所有者的执行权限的便利方法。
booleansetExecutable(boolean executable, boolean ownerOnly) 设置该抽象路径名的所有者或每个人的执行权限。
booleansetLastModified(long time) 设置由此抽象路径名命名的文件或目录的最后修改时间。
booleansetReadable(boolean readable) 一种方便的方法来设置所有者对此抽象路径名的读取权限。
booleansetReadable(boolean readable, boolean ownerOnly) 设置此抽象路径名的所有者或每个人的读取权限。
booleansetReadOnly() 标记由此抽象路径名命名的文件或目录,以便只允许读取操作。
booleansetWritable(boolean writable) 一种方便的方法来设置所有者对此抽象路径名的写入权限。
booleansetWritable(boolean writable, boolean ownerOnly) 设置此抽象路径名的所有者或每个人的写入权限。
PathtoPath() 返回从此抽象路径构造的java.nio.file.Path对象。
StringtoString() 返回此抽象路径名的路径名字符串。
URItoURI() 构造一个表示此抽象路径名的 file: URI。
URLtoURL() 已弃用 此方法不会自动转义URL中非法的字符。 建议在新的代码转换的抽象路径到URL通过先转换成URI,经由toURI方法,然后经由转换URI为URL URI.toURL方法。
1.3 基本使用
public static void main(String[] args) throws IOException {
        //1,在D:\\DiTian目录下创建一个文件file.txt
        File f1 = new File("D:\\DiTian\\file.txt");
        System.out.println(f1.createNewFile());
   		System.out.println("文件绝对路径:"+f1.getAbsolutePath());
        System.out.println("文件构造路径:"+f1.getPath());
        System.out.println("文件名称:"+f1.getName());
        System.out.println("文件长度:"+f1.length()+"字节");
    
        System.out.println("------------------");
        //2,在D:\\DiTian目录下创建文件夹java
        File f2 = new File("D:\\DiTian\\java");
        System.out.println(f2.mkdir());
        System.out.println("目录绝对路径:"+f2.getAbsolutePath());
        System.out.println("目录构造路径:"+f2.getPath());
        System.out.println("目录名称:"+f2.getName());
        System.out.println("目录长度:"+f2.length());
        System.out.println("------------------");
        //3,在D:\\DiTian目录下创建多级目录
        File f3 = new File("D:\\DiTian\\JavaWeb\\HTML");
        System.out.println(f3.mkdirs());
        System.out.println("------------------");
        File f4 = new File("D:\\DiTian");
        //4,返回此抽象路径名表示的目录中的文件和目录的名称字符串数组
        String[] list = f4.list();
        for (String s : list) {
            System.out.println(s);
        }
        System.out.println("------------------");
        //5,返回此抽象路径名表示的目录中的文件和目录的File对象数组
        File[] listFiles = f4.listFiles();
        for (File listFile : listFiles) {
            System.out.println(listFile);
        }
    }

delete方法:

public static void main(String[] args) throws IOException {
        // 文件的创建
        File f = new File("aaa.txt");
        System.out.println("是否存在:"+f.exists()); // false
        System.out.println("是否创建:"+f.createNewFile()); // true
        System.out.println("是否创建:"+f.createNewFile()); // 以及创建过了所以再使用createNewFile返回false
        System.out.println("是否存在:"+f.exists()); // true
		
     	// 目录的创建
      	File f2= new File("newDir");	
        System.out.println("是否存在:"+f2.exists());// false
        System.out.println("是否创建:"+f2.mkdir());	// true
        System.out.println("是否存在:"+f2.exists());// true

		// 创建多级目录
      	File f3= new File("newDira\\newDirb");
        System.out.println(f3.mkdir());// false
        File f4= new File("newDira\\newDirb");
        System.out.println(f4.mkdirs());// true
      
      	// 文件的删除
       	System.out.println(f.delete());// true
      
      	// 目录的删除
        System.out.println(f2.delete());// true
        System.out.println(f4.delete());// false
    }

2, I/O流

请添加图片描述

IO流的四点明确

(1)明确要操作的数据是数据源还是数据目的(要读还是要写)

源:
InputStream  Reader

目的:
OutputStream  Writer

(2)明确要操作的设备上的数据是字节还是文本

源:

字节: InputStream

文本: Reader

目的:

字节: OutputStream

文本: Writer

(3)明确数据所在的具体设备

源设备:

硬盘:文件 File开头

内存:数组,字符串

键盘:System.in

网络:Socket

对应目的设备:

硬盘:文件 File开头

内存:数组,字符串

屏幕:System.out

网络:Socket

(4)明确是否需要额外功能

需要转换—— 转换流 InputStreamReader 、OutputStreamWriter

需要高效—— 缓冲流Bufferedxxx

多个源—— 序列流 SequenceInputStream

对象序列化—— ObjectInputStream、ObjectOutputStream

保证数据的输出形式—— 打印流PrintStream 、Printwriter

操作基本数据,保证字节原样性——DataOutputStream、DataInputStream

2.1 字节流

在这里插入图片描述

2.1.1 FileOutputStream写出字节数据:

使用FileOutputStream写出字节数据主要通过Write方法,而write方法分如下三种

public void write(int b)
public void write(byte[] b)
public void write(byte[] b,int off,int len) //从off索引开始,len个字节

1, 写出字节:write(int b) 方法,每次可以写出一个字节数据,代码如下:

public class IoWrite {
    public static void main(String[] args) throws IOException {
        // 使用文件名称创建流对象
        FileOutputStream fos = new FileOutputStream("fos.txt");     
      	// 写出数据
      	fos.write(97); // 写出第1个字节
      	fos.write(98); // 写出第2个字节
      	fos.write(99); // 写出第3个字节
      	// 关闭资源
        fos.close();
    }
}
输出结果:
abc

2, 写出字节数组write(byte[] b),每次可以写出数组中的数据,代码使用演示:

public class FOSWrite {
    public static void main(String[] args) throws IOException {
        // 使用文件名称创建流对象
        FileOutputStream fos = new FileOutputStream("fos.txt");     
      	// 字符串转换为字节数组
      	byte[] b = "麻麻我想吃烤山药".getBytes();
      	// 写出字节数组数据
      	fos.write(b);
      	// 关闭资源
        fos.close();
    }
}
输出结果:
麻麻我想吃烤山药

3, 写出指定长度字节数组write(byte[] b, int off, int len) ,每次写出从off索引开始,len个字节,代码如下:

public class FOSWrite {
    public static void main(String[] args) throws IOException {
        // 使用文件名称创建流对象
        FileOutputStream fos = new FileOutputStream("fos.txt");     
      	// 字符串转换为字节数组
      	byte[] b = "abcde".getBytes();
		// 写出从索引2开始,2个字节。索引2是c,两个字节,也就是cd。
        fos.write(b,2,2);
      	// 关闭资源
        fos.close();
    }
}
输出结果:
cd

FileOutputStream实现数据追加续写、换行:

以上代码每次执行都会清空文件,重新进行写入,我们也可以对文件内容进行追加换行FileOutputStream的另外两个构造方法

1、public FileOutputStream(File file, boolean append)

2、public FileOutputStream(String name, boolean append)

这两个构造方法,第二个参数中都需要传入一个boolean类型的值,true 表示追加数据,false 表示不追加也就是清空原有数据。这样创建的输出流对象,就可以指定是否追加续写了。

public class FOSWrite {
    public static void main(String[] args) throws IOException {
        // 使用文件名称创建流对象
        FileOutputStream fos = new FileOutputStream("fos.txt"true);     
      	// 字符串转换为字节数组
      	byte[] b = "abcde".getBytes();
		// 写出从索引2开始,2个字节。索引2是c,两个字节,也就是cd。
        fos.write(b);
      	// 关闭资源
        fos.close();
    }
}
文件操作前:cd
文件操作后:cdabcde

Windows系统里,换行符号是 \r\n

public class FOSWrite {
    public static void main(String[] args) throws IOException {
        // 使用文件名称创建流对象
        FileOutputStream fos = new FileOutputStream("fos.txt");  
      	// 定义字节数组
      	byte[] words = {97,98,99,100,101};
      	// 遍历数组
        for (int i = 0; i < words.length; i++) {
          	// 写出一个字节
            fos.write(words[i]);
          	// 写出一个换行, 换行符号转成数组写出
            fos.write("\r\n".getBytes());
        }
      	// 关闭资源
        fos.close();
    }
}

输出结果:
a
b
c
d
e

回车符\r和换行符\n :
回车符:回到一行的开头(return)。
换行符:下一行(newline)。
系统中的换行:
Windows系统里,每行结尾是 回车+换行 ,即\r\n;
Unix系统里,每行结尾只有 换行 ,即\n;
Mac系统里,每行结尾是 回车 ,即\r。从 Mac OS X开始与Linux统一。

2.1.2 字节输入流

java.io.InputStream抽象类是表示字节输入流的所有类的超类(父类),可以读取字节信息到内存中。它定义了字节输入流的基本共性功能方法。

1、 public void close() :关闭此输入流并释放与此流相关联的任何系统资源。
2、public abstract int read(): 从输入流读取数据的下一个字节。

3、 public int read(byte[] b): 该方法返回的int值代表的是读取了多少个字节,读到几个返回几个,读取不到返回-1

FileInputStream的构造方法

1、 FileInputStream(File file): 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
2、 FileInputStream(String name): 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名name命名。

FileInputStream读取字节数据

1, 读取字节read方法,每次可以读取一个字节的数据,提升为int类型,读取到文件末尾,返回-1

public class FISRead {
    public static void main(String[] args) throws IOException{
      	// 使用文件名称创建流对象
       	FileInputStream fis = new FileInputStream("read.txt");
      	// 定义变量,保存数据
        int b ;
        // 循环读取
        while ((b = fis.read())!=-1) {
            System.out.println((char)b);
        }
		// 关闭资源
        fis.close();
    }
}
输出结果:
a
b
c
d
e

2, 使用字节数组读取read(byte[] b),每次读取b的长度个字节到数组中,返回读取到的有效字节个数,读取到末尾时,返回-1

public class FISRead {
    public static void main(String[] args) throws IOException{
      	// 使用文件名称创建流对象.
       	FileInputStream fis = new FileInputStream("read.txt"); // 文件中为abcde
      	// 定义变量,作为有效个数
        int len ;
        // 定义字节数组,作为装字节数据的容器   
        byte[] b = new byte[2];
        // 循环读取
        while (( len= fis.read(b))!=-1) {
           	// 每次读取后,把数组的有效字节部分,变成字符串打印
            System.out.println(new String(b,0,len));//  len 每次读取的有效字节个数
        }
		// 关闭资源
        fis.close();
    }
}

输出结果:
ab
cd
e

在开发中一般强烈推荐使用数据读取文件:

package io;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class input2 {
    public static void main(String args[]){
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream("a.txt");
            int len = 0 ;
            byte[] bys = new byte[1024];
            while ((len = inputStream.read(bys)) != -1) {
                System.out.println(new String(bys,0,len));
            }
        
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

2.2 字符流

在这里插入图片描述

字符流的由来:因为数据编码的不同,因而有了对字符进行高效操作的流对象,字符流本质其实就是基于字节流读取时,去查了指定的码表,而字节流直接读取数据会有乱码的问题(读中文会乱码:字节流读取中文字符时,可能不会显示完整的字符,那是因为一个中文字符占用多个字节存储,当然可以通过字节数组的形式来读取完整数据)

尽管字节流也能有办法决绝乱码问题,但是还是比较麻烦,于是java就有了字符流,字符为单位读写数据,字符流专门用于处理文本文件。如果处理纯文本的数据优先考虑字符流,其他情况就只能用字节流了(图片、视频、等等只文本例外)。

从另一角度来说:字符流 = 字节流 + 编码表

2.2.1 字符输入流(Reader)

java.io.Reader抽象类是字符输入流的所有类的超类(父类),可以读取字符信息到内存中。它定义了字符输入流的基本共性功能方法。

字符输入流的共性方法:

1、public void close() :关闭此流并释放与此流相关联的任何系统资源。
2、 public int read(): 从输入流读取一个字符。
3、 public int read(char[] cbuf): 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中

FileReader读取字符数据

1, 读取字符read方法,每次可以读取一个字符的数据,提升为int类型,读取到文件末尾,返回-1,循环读取

public class FRRead {
    public static void main(String[] args) throws IOException {
      	// 使用文件名称创建流对象
       	FileReader fr = new FileReader("a.txt");
      	// 定义变量,保存数据
        int b ;
        // 循环读取
        while ((b = fr.read())!=-1) {
            System.out.println((char)b);
        }
		// 关闭资源
        fr.close();
    }
}

2, 读取字符数组read(char[] chs),每次读取b的长度个字符到数组中,返回读取到的有效字符个数,读取到末尾时,返回-1

public class FRRead2 {
    public static void main(String[] args) throws IOException {
      	// 使用文件名称创建流对象
       	FileReader fr = new FileReader("a.txt");
      	// 定义变量,保存数据
        char[] chs = new char[1024];
        int b ;
        // 循环读取
        while ((b = fr.read(chs))!=-1) {
            System.out.println(new String(chs,0,len));
        }
		// 关闭资源
        fr.close();
    }
}

2.2.2 字符输出流(Writer)

java.io.Writer抽象类是字符输出流的所有类的超类(父类),将指定的字符信息写出到目的地。它同样定义了字符输出流的基本共性功能方法。

字符输出流的基本共性功能方法:

1、void write(int c) 写入单个字符。
2、void write(char[] cbuf)写入字符数组。
3、 abstract void write(char[] cbuf, int off, int len)写入字符数组的某一部分,off数组的开始索引,len写的字符个数。
4、 void write(String str)写入字符串。
5、void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数。
6、void flush()刷新该流的缓冲。
7、void close() 关闭此流,但要先刷新它。

构造方法

1、 FileWriter(File file): 创建一个新的 FileWriter,给定要读取的File对象。
2、FileWriter(String fileName): 创建一个新的 FileWriter,给定要读取的文件的名称。

FileWriter写出数据

1, 写出字符write(int b) 方法,每次可以写出一个字符数据

public class FWWrite {
    public static void main(String[] args) throws IOException {
        // 使用文件名称创建流对象
        FileWriter fw = new FileWriter("fw.txt");     
      	// 写出数据
      	fw.write(97); // 写出第1个字符
      	fw.write('b'); // 写出第2个字符
      	fw.write('C'); // 写出第3个字符
      	
        //关闭资源时,与FileOutputStream不同。 如果不关闭,数据只是保存到缓冲区,并未保存到文件。
        // fw.close();
    }
}
输出结果:
abC

【注意】关闭资源时,与FileOutputStream不同。 如果不关闭,数据只是保存到缓冲区,并未保存到文件。

关闭close和刷新flush
因为内置缓冲区的原因,如果不关闭输出流,无法写出字符到文件中。但是关闭的流对象,是无法继续写出数据的。如果我们既想写出数据,又想继续使用流,就需要flush 方法了。

flush :刷新缓冲区,流对象可以继续使用。
close: 先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。

public class FWWrite {
    public static void main(String[] args) throws IOException {
        // 使用文件名称创建流对象
        FileWriter fw = new FileWriter("fw.txt");
        // 写出数据,通过flush
        fw.write('刷'); // 写出第1个字符
        fw.flush();
        fw.write('新'); // 继续写出第2个字符,写出成功
        fw.flush();
      
      	// 写出数据,通过close
        fw.write('关'); // 写出第1个字符
        fw.close();
        fw.write('闭'); // 继续写出第2个字符,【报错】java.io.IOException: Stream closed
        fw.close();
    }
}

FileWriter的续写和换行

续写和换行:操作类似于FileOutputStream操作

public class FWWrite {
    public static void main(String[] args) throws IOException {
        // 使用文件名称创建流对象,可以续写数据
        FileWriter fw = new FileWriter("fw.txt"true);     
      	// 写出字符串
        fw.write("风花");
      	// 写出换行
      	fw.write("\r\n");
      	// 写出字符串
  		fw.write("雪月");
      	// 关闭资源
        fw.close();
    }
}
输出结果:
风华
雪月

FileReader和FileWriter类完成文本文件复制

public class CharStreamDemo {
    public static void main(String[] args) throws IOException {
        //创建字符输入流对象
        FileReader fr = new FileReader("D:\\DiTian\\file.txt");
        //创建字符输出流对象
        FileWriter fw = new FileWriter("D:\\DiTian\\file2.txt");
        //读写数据
        /*//单个字符
        int ch;
        while ((ch=fr.read())!=-1){
            fw.write(ch);
        }*/
        //字符数组
        char[] chs = new char[1024];
        int len;
        while ((len=fr.read(chs))!=-1){
            fw.write(chs,0,len);
        }
        System.out.println("复制成功!");
        fw.close();
        fr.close();
    }
}
2.3 缓冲流

缓冲流是对以上4种流的增强,也叫做高效流

缓冲流的基本原理:

1、使用了底层流对象从具体设备上获取数据,并将数据存储到缓冲区的数组内。
2、通过缓冲区的read()方法从缓冲区获取具体的字符数据,这样就提高了效率。
3、如果用read方法读取字符数据,并存储到另一个容器中,直到读取到了换行符时,将另一个容器临时存储的数据转成字符串返回,就形成了readLine()功能。

也就是说在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率。

缓冲书写格式为BufferedXxx,按照数据类型分类:

  • 字节缓冲流:BufferedInputStream,BufferedOutputStream
  • 字符缓冲流:BufferedReader,BufferedWriter
2.3.1 字节缓冲流

构造器举例:

//构造方式一: 创建字节缓冲输入流
FileInputStream fps = new FileInputStream(b.txt);
BufferedInputStream bis = new BufferedInputStream(fps)

//构造方式一: 创建字节缓冲输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("b.txt"));

///构造方式二: 创建字节缓冲输出流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("b.txt"));

对比字节流和字节缓冲流复制68M文件大小效率

基本字节流:

public class ByteStreamDemo {
    public static void main(String[] args) throws IOException {
        //记录开始时间
        long start = System.currentTimeMillis();
        //1,创建字节输入流对象
        FileInputStream fis = new FileInputStream("D:\\DiTian\\123.flv");
        //2,创建字节输出流对象
        FileOutputStream fos = new FileOutputStream("D:\\DiTian\\123copy.flv");
        byte[] bys1 = new byte[16*1024];
        int len1;
        //3,把输入流数据写入到输出文件
        while ((len1=fis.read(bys1))!=-1){
            fos.write(bys1,0,len1);
        }
        //记录结束时间
        long end = System.currentTimeMillis();
        System.out.println("复制成功!耗时:"+(end-start)+"毫秒");
        //关闭资源
        fos.close();
        fis.close();
    }
}


复制成功!耗时:539毫秒

字节缓冲流:

public class BufferStreamDemo {
    public static void main(String[] args) throws IOException {
        //记录开始时间
        long start = System.currentTimeMillis();
        //字节缓冲输入流:BufferedInputStream(InputStream in)
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\DiTian\\123.flv"));
        //字节缓冲输出流:BufferedOutputStream(OutputStream out)
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\DiTian\\123copy1.flv"));

        //字节数组读取
        byte[] bys = new byte[16*1024];
        int len;
        while ((len=bis.read(bys))!=-1){
            bos.write(bys,0,len);
        }
        //记录结束时间
        long end = System.currentTimeMillis();
        System.out.println("复制成功!耗时:" + (end-start)+"毫秒");
		//关闭资源
        bos.close();
        bis.close();
    }
}

复制成功!耗时:66毫秒

2.3.2 字符缓冲流

构造器举例:

// 创建字符缓冲输入流
BufferedReader br = new BufferedReader(new FileReader("b.txt"));
// 创建字符缓冲输出流
BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));

字符缓冲流除了基本字符流的方法外,还有其特有的方法:

  • BufferedReader:public String readLine(): 读一行数据。 读取到最后返回null
  • BufferedWriter:public void newLine(): 换行,由系统属性定义符号。
2.3 转换流

字符编码与解码简单一点的说就是:

编码:字符(能看懂的)–字节(看不懂的)

解码:字节(看不懂的)–>字符(能看懂的)

2.3.1 InputStreamReader类-----(字节流到字符流的桥梁)

转换流java.io.InputStreamReader,是Reader的子类,从字面意思可以看出它是从字节流到字符流的桥梁。它读取字节,并使用指定的字符集将其解码为字符。它的字符集可以由名称指定,也可以接受平台的默认字符集。

构造方法

InputStreamReader(InputStream in): 创建一个使用默认字符集的字符流。
InputStreamReader(InputStream in, String charsetName): 创建一个指定字符集的字符流。

使用转换流解决编码问题

public class ReaderDemo2 {
    public static void main(String[] args) throws IOException {
      	// 定义文件路径,文件为gbk编码
        String FileName = "C:\\A.txt";
      	// 创建流对象,默认UTF8编码
        InputStreamReader isr = new InputStreamReader(new FileInputStream(FileName));
      	// 创建流对象,指定GBK编码
        InputStreamReader isr2 = new InputStreamReader(new FileInputStream(FileName) , "GBK");
		// 定义变量,保存字符
        int read;
      	// 使用默认编码字符流读取,乱码
        while ((read = isr.read()) != -1) {
            System.out.print((char)read); // �����ʺ      
        }
        isr.close();
      
      	// 使用指定编码字符流读取,正常解析
        while ((read = isr2.read()) != -1) {
            System.out.print((char)read);// 风花雪月
        }
        isr2.close();
    }
}

2.3.2 OutputStreamWriter类-----(字符流到字节流的桥梁)

构造方法

OutputStreamWriter(OutputStream in): 创建一个使用默认字符集的字符流。
OutputStreamWriter(OutputStream in, String charsetName): 创建一个指定字符集的字符流。

代码示例:

public class OutputDemo {
    public static void main(String[] args) throws IOException {
      	// 定义文件路径
        String FileName = "C:\\s.txt";
      	// 创建流对象,默认UTF8编码
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(FileName));
        // 写出数据
      	osw.write("风花"); // 保存为6个字节
        osw.close();
      	
		// 定义文件路径
		String FileName2 = "D:\\A.txt";
     	// 创建流对象,指定GBK编码
        OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream(FileName2),"GBK");
        // 写出数据
      	osw2.write("雪月");// 保存为4个字节
        osw2.close();
    }
}

为了达到最高效率,可以考虑在 BufferedReader 字符缓冲流内包装 InputStreamReader

BufferedReader in = new BufferedReader(new InputStreamReader(System.in))

符集的字符流。

OutputStreamWriter(OutputStream in, String charsetName): 创建一个指定字符集的字符流。

代码示例:

public class OutputDemo {
    public static void main(String[] args) throws IOException {
      	// 定义文件路径
        String FileName = "C:\\s.txt";
      	// 创建流对象,默认UTF8编码
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(FileName));
        // 写出数据
      	osw.write("风花"); // 保存为6个字节
        osw.close();
      	
		// 定义文件路径
		String FileName2 = "D:\\A.txt";
     	// 创建流对象,指定GBK编码
        OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream(FileName2),"GBK");
        // 写出数据
      	osw2.write("雪月");// 保存为4个字节
        osw2.close();
    }
}

为了达到最高效率,可以考虑在 BufferedReader 字符缓冲流内包装 InputStreamReader

BufferedReader in = new BufferedReader(new InputStreamReader(System.in))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值