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 实例。 |
所有方法:
boolean | canExecute() 测试应用程序是否可以执行此抽象路径名表示的文件。 |
---|---|
boolean | canRead() 测试应用程序是否可以读取由此抽象路径名表示的文件。 |
boolean | canWrite() 测试应用程序是否可以修改由此抽象路径名表示的文件。 |
int | compareTo(File pathname) 比较两个抽象的路径名字典。 |
boolean | createNewFile() 当且仅当具有该名称的文件尚不存在时,原子地创建一个由该抽象路径名命名的新的空文件。 |
static File | createTempFile(String prefix, String suffix) 在默认临时文件目录中创建一个空文件,使用给定的前缀和后缀生成其名称。 |
static File | createTempFile(String prefix, String suffix, File directory) 在指定的目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。 |
boolean | delete() 删除由此抽象路径名表示的文件或目录。 |
void | deleteOnExit() 请求在虚拟机终止时删除由此抽象路径名表示的文件或目录。 |
boolean | equals(Object obj) 测试此抽象路径名与给定对象的相等性。 |
boolean | exists() 测试此抽象路径名表示的文件或目录是否存在。 |
File | getAbsoluteFile() 返回此抽象路径名的绝对形式。 |
String | getAbsolutePath() 返回此抽象路径名的绝对路径名字符串。 |
File | getCanonicalFile() 返回此抽象路径名的规范形式。 |
String | getCanonicalPath() 返回此抽象路径名的规范路径名字符串。 |
long | getFreeSpace() 返回分区未分配的字节数 named此抽象路径名。 |
String | getName() 返回由此抽象路径名表示的文件或目录的名称。 |
String | getParent() 返回此抽象路径名的父 null 的路径名字符串,如果此路径名未命名为父目录,则返回null。 |
File | getParentFile() 返回此抽象路径名的父,或抽象路径名 null 如果此路径名没有指定父目录。 |
String | getPath() 将此抽象路径名转换为路径名字符串。 |
long | getTotalSpace() 通过此抽象路径名返回分区 named的大小。 |
long | getUsableSpace() 返回上的分区提供给该虚拟机的字节数 named此抽象路径名。 |
int | hashCode() 计算此抽象路径名的哈希码。 |
boolean | isAbsolute() 测试这个抽象路径名是否是绝对的。 |
boolean | isDirectory() 测试此抽象路径名表示的文件是否为目录。 |
boolean | isFile() 测试此抽象路径名表示的文件是否为普通文件。 |
boolean | isHidden() 测试此抽象路径名命名的文件是否为隐藏文件。 |
long | lastModified() 返回此抽象路径名表示的文件上次修改的时间。 |
long | length() 返回由此抽象路径名表示的文件的长度。 |
String[] | list() 返回一个字符串数组,命名由此抽象路径名表示的目录中的文件和目录。 |
String[] | list(FilenameFilter filter) 返回一个字符串数组,命名由此抽象路径名表示的目录中满足指定过滤器的文件和目录。 |
File[] | listFiles() 返回一个抽象路径名数组,表示由该抽象路径名表示的目录中的文件。 |
File[] | listFiles(FileFilter filter) 返回一个抽象路径名数组,表示由此抽象路径名表示的满足指定过滤器的目录中的文件和目录。 |
File[] | listFiles(FilenameFilter filter) 返回一个抽象路径名数组,表示由此抽象路径名表示的满足指定过滤器的目录中的文件和目录。 |
static File[] | listRoots() 列出可用的文件系统根。 |
boolean | mkdir() 创建由此抽象路径名命名的目录。 |
boolean | mkdirs() 创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录。 |
boolean | renameTo(File dest) 重命名由此抽象路径名表示的文件。 |
boolean | setExecutable(boolean executable) 为此抽象路径名设置所有者的执行权限的便利方法。 |
boolean | setExecutable(boolean executable, boolean ownerOnly) 设置该抽象路径名的所有者或每个人的执行权限。 |
boolean | setLastModified(long time) 设置由此抽象路径名命名的文件或目录的最后修改时间。 |
boolean | setReadable(boolean readable) 一种方便的方法来设置所有者对此抽象路径名的读取权限。 |
boolean | setReadable(boolean readable, boolean ownerOnly) 设置此抽象路径名的所有者或每个人的读取权限。 |
boolean | setReadOnly() 标记由此抽象路径名命名的文件或目录,以便只允许读取操作。 |
boolean | setWritable(boolean writable) 一种方便的方法来设置所有者对此抽象路径名的写入权限。 |
boolean | setWritable(boolean writable, boolean ownerOnly) 设置此抽象路径名的所有者或每个人的写入权限。 |
Path | toPath() 返回从此抽象路径构造的java.nio.file.Path 对象。 |
String | toString() 返回此抽象路径名的路径名字符串。 |
URI | toURI() 构造一个表示此抽象路径名的 file: URI。 |
URL | toURL() 已弃用 此方法不会自动转义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));