Table of Contents
1.1.2: 通过 FileSystems 类和 和 FileSystem 类建 创建 Path 对象
2.1:public boolean isWritable(Path path) 判断文件是否可被写入
2.2:public boolean isExecutable(Path path) 判断文件是否存在
2.3:public static Path createFile(Path path,FileAttribute... attrs) 创建一个新的空文件,如果文件已经存在,则抛出异常
2.4:public static boolean isSameFile(Path p1,Path p2) 判断两个文件是否是同一个文件
2.5:public static long size(Path path) 获取文件的长度,单位是字节
2.6:public static boolean isDirectory(Path path) 测试文件是否为目录
2.7.1:public static Stream list(Path dir) 遍历子文件(只遍历目录下一级)--参数是目录;返回一个 stream 流,其元素是目录中的条目。
2.7.4:public static DirectoryStream newDirectoryStream(Path dir,String glob) --- 正则表达式过滤
2.8.2:public static Stream walk(Path start,FileVisitOption... options)
2.8.3:public static Path walkFileTree(Path start,FileVisitor visitor)
2.9.1:public static Path createDirectory(Path dir,FileAttribute... attrs)创建一个新的目录,但是父目录必须存在
2.9.2:public static Path createDirectories(Path dir,FileAttribute... attrs)可以先创建不存在的父目录
2.10.1:public boolean delete(Path path) 删除文件,如果文件不存在,抛异常。
2.10.2:public boolean deleteIfExists() 删除文件(如果存在),如果文件不存在,什么也不做。
2.11.1:public static InputStream newInputStream(Path path,OpenOption...options)
2.11.2:public static OutputStream newOutputStream(Path path,OpenOption... options)
2.12:读取字节数组public static byte[] readAllBytes(Path path)从文件中读取所有
2.13:读取字符串public static List readAllLines(Path path)
2.14.1---public static Path write(Path path,byte[] bytes, OpenOption...options)将字节写入文件
2.14.2:public static Path write(Path path,Iterable lines,OpenOption... options)---将文本行写入文件中
2.15:public static Path move(Path source, Path target,CopyOption...options)将文件移动或重命名为目标文件。
6.1 ObjectInputStream 和 和 ObjectOutputStream
I/O流
1:Path和Paths类
Path 用于来表示文件路径和文件,用来获取文件本身的一些信息,例如文件所在的目录,文件的长度,文件读写权限等。
1.1:创建Path对象
1.1.1:通过Paths类来创建Path对象
Path path = Paths.get("C:\\Users\\86156\\Desktop\\test.txt");
Path path1 = Paths.get("C:\\Users\\86156\\Desktop","test.txt");
1.1.2: 通过 FileSystems 类和 和 FileSystem 类建 创建 Path 对象
Path path2 = FileSystems.getDefault().getPath("C:\\Users\\86156\\Desktop\\test.txt");
1.1.3:通过File对象换成Path对象
File 类是 jdk7 之前的文件类,jdk7 之后被 Path 类替代。
File file = new File("C:\\Users\\86156\\Desktop\\test.txt");
Path path3 = file.toPath();
1.2:Path类的方法
1.2.1:名称
public Path getFileName() ----返回此路径对象表示的文件或目录的名称。
Path path = Paths.get("C:\\Users\\86156\\Desktop\\test.txt");
System.out.println(""+path.getFileName());//test.txt
1.2.2:路径
public int getNameCount() --- 返回路径中的文件名称的数目,即该路径一共几层;
Path path = Paths.get("C:\\Users\\86156\\Desktop\\test.txt");
int nameCount = path.getNameCount();
System.out.println(""+nameCount);//4
public Path getName(int index) --- 返回路径中指定位置的文件名称
Path path = Paths.get("C:\\Users\\86156\\Desktop\\test.txt");
int nameCount = path.getNameCount();
System.out.println(""+nameCount);//4
Path name0 = path.getName(0);
Path name1 = path.getName(1);
Path name2 = path.getName(2);
Path name3 = path.getName(3);
System.out.println(""+name0);//Users
System.out.println(""+name1);//86156
System.out.println(""+name2);//Desktop
System.out.println(""+name3);//test.txt
public Path getParent()---返回此路径的父路径,如果该路径没有父路径,则返回 null
Path path = Paths.get("C:\\Users\\86156\\Desktop\\test.txt");
Path parent = path.getParent();
System.out.println(""+parent);//C:\Users\86156\Desktop
public Path getRoot() --- 返回此路径的根路径,如果该路径没有根路径,则返回 null
Path path = Paths.get("C:\\Users\\86156\\Desktop\\test.txt");
Path root = path.getRoot();
System.out.println(""+root);//C:\
public boolean isAbsolute() --- 如果此路径是绝对路径,则返回 true
Path path = Paths.get("C:\\Users\\86156\\Desktop\\test.txt");
boolean absolute = path.isAbsolute();
System.out.println(""+absolute);//true
Path path1 = Paths.get("hello.txt");
boolean absolute1 = path1.isAbsolute();
System.out.println(""+absolute1);//false
1.2.3:新路径
public Path resolve(String path) --- 在此路径下将给定的路径字符串转换为新路径
Path path = Paths.get("C:\\Users\\86156\\Desktop");
Path resolve = path.resolve("123");
System.out.println(""+resolve);//C:\Users\86156\Desktop\123
public Path resolveSibling(String path)在此路径的父路径下将给定的路径字符转成新的路径
Path path = Paths.get("C:\\Users\\86156\\Desktop");
Path resolve = path.resolve("123");
System.out.println(""+resolve);//C:\Users\86156\Desktop\123
Path resolveSibling = resolve.resolveSibling("456");
System.out.println(""+resolveSibling);//C:\Users\86156\Desktop\456
public Path toAbsolutePath()返回此路径的绝对路径
Path path = Paths.get("hello");
Path path1 = path.toAbsolutePath();
System.out.println(""+path1);//F:\idea-workpase\helloidea\hello这是该项目的路径
2:Files类,对文件进行操作
这个类完全由操作文件、目录或其他类型文件的静态方法组成。在大多数情况下,这里定义的方法将委托相关的文件系统提供程序来执行文件操作。
2.1:public boolean isWritable(Path path) 判断文件是否可被写入
//如果文件不存在时不可以写入的
Path path = Paths.get("hello.txt");
Path path1 = path.toAbsolutePath();
System.out.println(""+path1);//F:\idea-workpase\helloidea\hello.txt这是该项目的路径
boolean writable = Files.isWritable(path);
System.out.println(""+writable);//true
2.2:public boolean isExecutable(Path path) 判断文件是否存在
boolean executable = Files.isExecutable(path);
System.out.println(""+executable);//true
2.3:public static Path createFile(Path path,FileAttribute<?>... attrs) 创建一个新的空文件,如果文件已经存在,则抛出异常
Path path = Paths.get("hello1.txt");
Path file = Files.createFile(path);
System.out.println(""+file);//hello1.txt
创建文件时,指定文件属性。(Linux)
Path p1 = Paths.get("hello.txt");
Set perms= PosixFilePermissions.fromString("rw-rw-rw-");
FileAttribute attrs = PosixFilePermissions.asFileAttribute(perms);
Files.createFile(p1,attrs);
2.4:public static boolean isSameFile(Path p1,Path p2) 判断两个文件是否是同
一个文件
Path path = Paths.get("hello.txt");
Path path1 = Paths.get("hello1.txt");
boolean sameFile = Files.isSameFile(path, path1);
System.out.println(""+sameFile);
2.5:public static long size(Path path) 获取文件的长度,单位是字节
Path path = Paths.get("hello.txt");
long size = Files.size(path);
System.out.println(""+size);
2.6:public static boolean isDirectory(Path path) 测试文件是否为目录
Path path = Paths.get("hello.txt");
boolean directory = Files.isDirectory(path);
System.out.println(""+directory);
2.7:遍历子文件---只遍历目录下一级
2.7.1:public static Stream<Path> list(Path dir) 遍历子文件(只遍历目录下一级)--参数是目录;返回一个 stream 流,其元素是目录中的条目。
2.7.2:public static DirectoryStream<Path> newDirectoryStream(Path dir)打开目录,返回一个 DirectoryStream 遍历目录中的所有条目。可以使用迭代器遍历
Path path = Paths.get("F:/");
DirectoryStream<Path> paths = Files.newDirectoryStream(path);
for(Path file:paths){
System.out.println(""+file);
}
2.7.3:public static DirectoryStream<Path> newDirectoryStream(Path dir,
DirectoryStream.Filter<? super Path> filter)) --- 通过 Filter 接口过滤子文件
Path path = Paths.get("F:/");
DirectoryStream<Path> paths = Files.newDirectoryStream(path,p->Files.size(p)>1024);
for(Path file:paths){
System.out.println(""+file);
}
2.7.4:public static DirectoryStream<Path> newDirectoryStream(Path dir,String glob) --- 正则表达式过滤
Path path = Paths.get("F:/");
DirectoryStream<Path> paths = Files.newDirectoryStream(path,"S*");
for(Path file:paths){
System.out.println(""+file);
}
2.8:遍历目录树---查询目录下所有的文件,包括向里延伸
2.8.1:public static Stream<Path> find(Path start,int maxDepth,BiPredicate<Path,BasicFileAttributes> matcher,FileVisitOption... options)通过在给定的起始文件中,搜索文件树中的文件,返回一个被路径填充的流。
start
- 起始文件
maxDepth
- 要搜索的目录级别的最大数量
matcher
- 用于决定文件是否应包含在返回的流中的函数
options
- 配置遍历的选项
Path p1 = Paths.get("F:\\idea-workpase");
//搜索文件树中满足要求的文件
Stream<Path> ps= Files.find(p1, Integer.MAX_VALUE,(p,a)->p.endsWith("hello.txt"));
//循环输出查询结果
ps.forEach(p->System.out.println(p));
2.8.2:public static Stream<Path> walk(Path start,FileVisitOption... options)
返回一个Stream
,它通过走根据给定起始文件的文件树懒惰地填充Path
。 文件树以深度优先的方式遍历 ,流中的元素是Path
对象,如resolving
所示 ,相对路径为start
。
start
- 起始文件
options
- 配置遍历的选项
这个方法的工作原理就像调用它相当于评估表达式:
walk(start, Integer.MAX_VALUE, options)
Path p1 = Paths.get("F:\\idea-workpase");
//搜索文件树中满足要求的文件
Stream<Path> walk = Files.walk(p1);
walk.forEach(path -> {System.out.println(""+path);});
2.8.3:public static Path walkFileTree(Path start,FileVisitor<? super Path> visitor)
//接口方法的返回值FileVisitResult是一个枚举类型,
//walkFileTree会根据这个返回值决定是否要继续遍历下去,
//它总共有 4 个枚举值:
//CONTINUE:继续遍历
//SKIP_SIBLINGS:继续遍历,但忽略当前节点的所有兄弟节点直接返回上一层继续遍历
//SKIP_SUBTREE:继续遍历,但是忽略子目录,但是子文件还是会访问;
//TERMINATE:终止遍历
public class TestMain {
public static void main(String[] args) throws IOException {
Path p1 = Paths.get("F:\\idea-workpase\\helloidea\\src\\timeTask");
//搜索文件树中满足要求的文件
//接口方法的返回值FileVisitResult是一个枚举类型,
//walkFileTree会根据这个返回值决定是否要继续遍历下去
//CONTINUE:继续遍历
//SKIP_SIBLINGS:继续遍历,但忽略当前节点的所有兄弟节点直接返回上一层继续遍历
//SKIP_SUBTREE:继续遍历,但是忽略子目录,但是子文件还是会访问;
//TERMINATE:终止遍历
Files.walkFileTree(p1, new FileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
//访问目录前
System.out.println("start");
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
//访问文件时
System.out.println(""+file.getFileName());
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
//访问文件失败
System.out.println("failed:"+file.getFileName());
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
//访问目录后
System.out.println("end");
return FileVisitResult.CONTINUE;
}
});
}
}
2.9:创建目录
2.9.1:public static Path createDirectory(Path dir,FileAttribute<?>... attrs)创建一个新的目录,但是父目录必须存在
public static void main(String[] args) throws IOException {
Path path = Paths.get("F:\\1");
//如果父类不存在,那么就会跑出异常
Path directory = Files.createDirectory(path);
System.out.println(""+directory);
}
2.9.2:public static Path createDirectories(Path dir,FileAttribute<?>... attrs)可以先创建不存在的父目录
public static void main(String[] args) throws IOException {
Path path = Paths.get("F:\\1\\2");
//如果父目录不存在,那么就会先创建父目录
Path directory = Files.createDirectories(path);
System.out.println(""+directory);
}
2.10:删除
2.10.1:public boolean delete(Path path) 删除文件,如果文件不存在,抛异常。
2.10.2:public boolean deleteIfExists() 删除文件(如果存在),如果文件不存在,什么也不做。
2.11:生成字节流InputStream
2.11.1:public static InputStream newInputStream(Path path,OpenOption...options)
打开一个文件,返回一个输入流以从文件中读取文件。
public class Test2 {
public static void main(String[] args) throws IOException {
Path path = Paths.get("");
InputStream inputStream = Files.newInputStream(path);
}
}
2.11.2:public static OutputStream newOutputStream(Path path,OpenOption... options)
打开或创建一个文件,返回一个输出流,该字节流可用于写入文件的字节。
public class Test2 {
public static void main(String[] args) throws IOException {
Path path = Paths.get("");
OutputStream outputStream = Files.newOutputStream(path);
}
}
2.12:读取字节数组public static byte[] readAllBytes(Path path)从文件中读取所有
字节
public class Test2 {
public static void main(String[] args) throws IOException {
Path path = Paths.get("");
byte[] bytes = Files.readAllBytes(path);
}
}
2.13:读取字符串public static List<String> readAllLines(Path path)
public class Test2 {
public static void main(String[] args) throws IOException {
Path path = Paths.get("C:\\Users\\86156\\Desktop\\test.txt");
List<String> strings = Files.readAllLines(path);
for(String str:strings){
System.out.println(""+str);
}
}
}
2.14:写入字符串
2.14.1---public static Path write(Path path,byte[] bytes, OpenOption...options)将字节写入文件
public class Test2 {
public static void main(String[] args) throws IOException {
Path path = Paths.get("C:\\Users\\86156\\Desktop\\test.txt");
//追加
Path write = Files.write(path, "4444444444".getBytes(), StandardOpenOption.APPEND);
}
}
2.14.2:public static Path write(Path path,Iterable<? extends CharSequence> lines,
OpenOption... options)---将文本行写入文件中
public class Test2 {
public static void main(String[] args) throws IOException {
Path path = Paths.get("C:\\Users\\86156\\Desktop\\test.txt");
List<String> list = new ArrayList<>();
list.add("aaaaa");
list.add("bbbbb");
//追加
Path write = Files.write(path,list , StandardOpenOption.APPEND);
}
}
2.15:public static Path move(Path source, Path target,CopyOption...options)
将文件移动或重命名为目标文件。
public class Test2 {
public static void main(String[] args) throws IOException {
Path path = Paths.get("C:\\Users\\86156\\Desktop\\test.txt");
Path path1 = Paths.get("C:\\Users\\86156\\Desktop\\test1.txt");
Path copy = Files.copy(path, path1);
}
}
3:流的概念
流是字节从源到目的的轨迹,次序是有意义的。
4: FileInputStream类
如果需要从本地硬盘读取文件,可以使用 FileInputStream 类,该类是从 InputStream中派生出来的简单输入类。该类的所有方法都是从 InputStream 类继承来的。为了创建FileInputStream 类的对象,可以调用下面两个构造方法:
- FileInputStream(String name)
- FileInputStream(File file)
第一个构造器使用给定的文件名 name 创建一个 FileInputStream 对象,第二个构造器使用 File 对象创建 FileInputStream 对象。
4.1:创建文件输入流
public class Test2 {
public static void main(String[] args) throws IOException {
File file = new File("C:\\Users\\86156\\Desktop\\test.txt");
FileInputStream fileInputStream = new FileInputStream(file);
}
}
4.2:从输入流中读取字节
输入流的唯一目的是提供通往数据的通道,程序可以通过这个通道读取数据。Read 方法给程序提供一个从输入流中读取数据的基本方法
4.2.1:int read( )
从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1 。
4.2.2:int read(byte[] b)
从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。以整数形式返回实际读取的字节数。如果遇到输入流的结尾,则返回 -1 。
FileInputStream 流顺序地读取文件,只要不关闭流,每次调用 read 方法就顺序地读取源其余的内容,直到流的末尾或流被关闭。
4.2.3:示例
public class Test2 {
public static void main(String[] args) throws IOException {
File file = new File("C:\\Users\\86156\\Desktop\\test.txt");
FileInputStream fileInputStream = new FileInputStream(file);
byte[] b =new byte[20];
int i=0;
while ((i=fileInputStream.read(b))!=(-1)){
System.out.println(""+i);
System.out.println(""+ Arrays.toString(b));
}
}
}
4.3:关闭流
我们使用完流后,显式地关闭任何打开的流仍是一个良好的习惯。
public class Test2 {
public static void main(String[] args){
FileInputStream fileInputStream = null;
try {
File file = new File("C:\\Users\\86156\\Desktop\\test.txt");
fileInputStream = new FileInputStream(file);
byte[] b =new byte[20];
int i=0;
while ((i=fileInputStream.read(b))!=(-1)){
System.out.println(""+i);
System.out.println(""+ new String(b));
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
5:FileOutputStream 类
与 FileInputStream 类相对应的类是 FileOutputStream 类。FileOutputStream 提供了基本的文件写入能力。FileOutputStream 类有两个构造方法:
- FileOutputStream(String name)
- FileOutputStream(File file)
FileOutputStream 类有三个基本的 write()方法
- void write(int n)
- void write(byte b[])
- void write(byte b[], int off, int len)
这些方法写输出流。和输入一样,总是尝试以实际最大的块进行写操作
- void close()
当你完成写操作后,就关闭输出流。如果你有一个流所组成的栈,就关闭栈顶部的流。 这个关闭操作会关闭其余的流
- void flush()
有时一个输出流在积累了若干次之后才进行真正的写操作。flush()方法允许你强制执行写操作。
public class Test2 {
public static void main(String[] args){
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
File file = new File("C:\\Users\\86156\\Desktop\\test.txt");
fileInputStream = new FileInputStream(file);
fileOutputStream = new FileOutputStream(new File("C:\\Users\\86156\\Desktop\\testhello.txt"));
byte[] b =new byte[20];
int i=0;
while ((i=fileInputStream.read(b))!=(-1)){
System.out.println(""+i);
System.out.println(""+ new String(b));
fileOutputStream.write(b,0,i);
fileOutputStream.flush();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fileInputStream.close();
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
6:对象字节流
6.1 ObjectInputStream 和 和 ObjectOutputStream
ObjectInputStream 类 和 ObjectOutputStream 类 分 别 是 InputStream 类 和OutputStream 类的子类。ObjectInputStream 类和 ObjectOutputStream 类创建的对象被称为对象输入流和对象输出流。
对象输出流使用 writeObject(Object obj)方法将一个对象 obj 写入到一个文件,对象输入流使用 readObject()读取一个对象到程序中。ObjectInputStream 类和 ObjectOutputStream 类的构造方法分别是:
- ObjectInputStream(InputStream in)
- ObjectOutputStream(OutputStream out)
示例:
public class Test3 {
public static void main(String[] args) {
File file = new File("C:\\Users\\86156\\Desktop\\date.txt");
FileOutputStream fileOutputStream = null;
ObjectOutputStream objectOutputStream = null;
try {
fileOutputStream = new FileOutputStream(file);
objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(new Date());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
objectOutputStream.close();
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
6.2:串行化
将一个对象存放到某种类型的永久存储器上称为保持。如果一个对象可以被存放到磁盘或磁带上,或者可以发送到另外一台机器并存放到存储器或磁盘上,那么这个对象就被称为可保持的。java.io.Serializable 接口没有任何方法,它只作为一个“标记者”,用来表明实现了这个接口的类可以考虑串行化。类中没有实现 Serializable 的对象不能保存或恢复它们的状态。
串行化的类必须实现:Serializable接口
public class MyClass implements Serializable {
7:缓冲字节流
java.io.BufferedInputStream 与 java.io.BufferedOutputStream 可 以 为InputStream、OutputStream 类增加缓冲区功能。构建 BufferedInputStream 实例时,需要给定一个 InputStream 类型的实例,实现 BufferedInputStream 时,实际上最后是实
现 InputStream 实例。
BufferedInputStream 的数据成员 buf 是一个位数组,默认为 2048 字节。当读取数据来源时,例如文件,BufferedInputStream 会尽量将 buf 填满。当使用 read()方法时,实际上是先读取 buf 中的数据,而不是直接对数据来源作读取。当 buf 中的数据不足时,BufferedInputStream 才会再实现给定的 InputStream 对象的 read()方法,从指定的装置中提取数据。
public class Test2 {
public static void main(String[] args){
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
BufferedInputStream bufferedInputStream = null;
BufferedOutputStream bufferedOutputStream = null;
try {
File file = new File("C:\\Users\\86156\\Desktop\\test.txt");
fileInputStream = new FileInputStream(file);
fileOutputStream = new FileOutputStream(new File("C:\\Users\\86156\\Desktop\\testhello.txt"));
bufferedInputStream = new BufferedInputStream(fileInputStream);
bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
byte[] b =new byte[20];
int i=0;
while ((i=bufferedInputStream.read(b))!=(-1)){
System.out.println(""+i);
System.out.println(""+ new String(b));
bufferedOutputStream.write(b,0,i);
bufferedOutputStream.flush();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fileInputStream.close();
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
8:数据字节流
DataInputStream 类 和 DataOutputStream 类创建的对象被称为数据输入流和数据输出流。数据流允许程序按照机器无关的风格读取操作数据,也就是当我们操作一个数据时,不必关心这个数值应当是多少个字节。
操作与上述类似,不同的是直接对读写的类型进行操作;
9:字符流
9.1:Reader 和 Writer
Java 技术使用 Unicode 来表示字符串和字符,而且它提供了 16 位版本的流,以便用类似的方法来处理字符。这些 16 位版本的流称为读者和作者。和流一样,它们都在 java.io包中。 读者和作者中最重要的版本是 InputStreamReader 和 OutputStreamWriter。这些类用来作为字节流与读者和作者之间的接口。
字符流在进行中文操作时会更加方便和准确,比如在读取中文文档内容时,字节流可能会读取到中文的一半,而字符流则不会出现这样的问题。
这样用字节流读,中文有可能是乱码;
FileInputStream fis = null;
try {
File f = new File("test.txt");
// 创建字节流
fis = new FileInputStream(f);
// 创建字节数组,每次读取 5 个字节
byte[] arr = new byte[5];
// 读取的字节长度
int length=0;
while((length=fis.read(arr))!=-1){
// 将读取的数据转换成String
String msg = new String(arr,0,length);
//输出
System.out.print(msg);
}
} catch (IOException e) {
// 文件不存在异常
System.out.println("File read error:" + e);
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
但是用字符流读,就没事
FileInputStream fis = null;
InputStreamReader reader = null;
try {
File f = new File("test.txt");
// 创建字节流
fis = new FileInputStream(f);
// 创建字符流
reader = new InputStreamReader(fis);
// 创建字符数组,每次读取 5 个字符
char[] arr = new char[5];
// 读取的字符长度
int length = 0;
while ((length = reader.read(arr)) != -1) {
// 将读取的数据转换成String
String msg = new String(arr, 0, length);
// 输出
System.out.print(msg);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
9.2:缓冲读者和缓冲作者
他们和InputStreamReader 以及OutputStreamReader的区别就在于,他们有一个长度为8192字节的char[]数组,每次写文件都是先向缓冲区中写入,等缓冲区满了,则数据写入硬盘,如果没满,继续等待,如果最中没慢,需要关闭流后者fulsh流,也会把数据写入硬盘;