14 IO
file类概述
java.io.File类 文件和目录路径名的抽象表示形式。 java把电脑中的文件和文件夹(目录)封装为了一个File类,我们可以使用File类对文件和文件夹进行操作
我们可以使用File类的方法 创建一个文件/文件夹 删除文件/文件夹获取文件/文件夹 判断文件/文件夹是否存在 对文件夹进行遍历 获取文件的大小 File类是一个与系统无关的类,任何的操作系统都可以使用这个类中的方法
重点:记住这三个单词 file:文件 directory:文件夹/目录 path:路径
file类静态变量
package file;
import java.io.File;
public class Demo01 {
public static void main(String[] args) {
/*
static String pathSeparator 与系统有关的路径分隔符,为了方便,它被表示为一个字符串。
static char pathseparatorchar 与系统有关的路径分隔符。
static String separator 与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串。
static char separatorchar 与系统有关的默认名称分隔符。
操作路径:路径不能写死了
C:\develop\a\a.txt windows
C:/develop/a/a.txt Linux
"C:"+File.separator+"develop"+File.separator+"a"+File.separator+"a.txt"
*/
String pathSeparator = File.pathSeparator;
System.out.println(pathSeparator);//路径分隔符 Windows:分号; linux: 冒号 :
String separator = File.separator;
System.out.println(separator);//文件名称分隔符 Windows:反斜杠\ linux: 正斜杠 /
}
}
file类的构造方法
第一种
package file.Demo01;
import java.io.File;
/*
路径:
绝对路径:是一个完整的路径
以盘符(C:,D:)开始的路径
c:\\a.txt
C:\\Users\itcast\\IdeaProjects\\shungyuan\\123.txt D:1I demol lb.txt
相对路径:是一个简化的路径
相对指的是相对于当前项目的根目录(C:\\Users\itcast\\IdeaProjects\\shungyuan)
如果使用当前项目的根目录,路径可以简化书写
C:\\Users\itcast\\IdeaProjects\\shungyuan\\123.txt-->简化为:123.txt(可以省略项目的根目录)
注意:
1.路径是不区分大小写
2.路径中的文件名称分隔符windows使用反斜杠,反斜杠是转义字符,两个反斜杠代表一个普通的反斜杠
*/
public class Demo02 {
public static void main(String[] args) {
/*
File类的构造方法
*/
show01();
}
/*
File(String pathname)
通过将给定路径名字符串转换为抽象路径名来创建一个新File实例。
参数:
String pathname:字符串的路径名称
路径可以是以文件结尾,也可以是以文件夹结尾
路径可以是相对路径,也可以是绝对路径
路径可以是存在,也可以是不存在
创建File对象,只是把字符串路径封装为File对象,不考虑路径的真假情况
*/
private static void show01(){
File f1 = new File("C:\\t430\\java\\code\\heima\\src\\a.txt");
System.out.println(f1);//重写了object类里的toString方法 C:\t430\java\code\heima\src\a.txt
File f2 = new File("C:\\t430\\java\\code\\heima\\src");
System.out.println(f2);
File f3 = new File("b.txt");
System.out.println(f3);
}
}
第二种
package file.Demo01;
import java.io.File;
public class Demo02 {
public static void main(String[] args) {
/*
File类的构造方法
*/
show02("c:\\","a.txt");
}
/*
File(String parent,String child)
根据parent路径名字符串和child路径名字符串创建一个新File实例。
参数:把路径分成了两部分
String parent:父路径
String child:子路径
好处:父路径和子路径,可以单独书写,使用起来非常灵活;父路径和子路径都可以变化
*/
private static void show02(String parent,String child){
File file = new File(parent,child);
System.out.println(file);
}
}
第三种
package file.Demo01;
import java.io.File;
public class Demo03 {
public static void main(String[] args) {
/*
File类的构造方法
*/
show03();
}
/*
File(File parent,String child)根据 parent 抽象路径名和 child 路径名字符串创建一个新File实例。
参数:把路径分成了两部分
File parent:父路径
string child:子路径
好处:
父路径和子路径,可以单独书写,使用起来非常灵活;父路径和子路径都可以变化
父路径是File类型,可以使用File的方法对路径进行一些操作,再使用路径创建对象
*/
private static void show03(){
File parent = new File("c:\\");
File file = new File(parent,"hello.java");
System.out.println(file);
}
}
File类获取功能的方法
package file.Demo01;
import java.io.File;
/*
File类获取功能的方法
public String getAbsolutePath():返回此File的绝对路径名字符串。
public string getPath():将此File转换为路径名字符串。
public String getName():返回由此File表示的文件或目录的名称。
public long Length():返回由此File表示的文件的长度。
*/
public class Demo02 {
public static void main(String[] args) {
show01();
show02();
show03();
show04();
}
/*
public string getAbsolutePath():返回此File的绝对路径名字符串。
获取的构造方法中传递的路径
无论路径是绝对的还是相对的,getAbsolutePath方法返回的都是绝对路径
*/
/*
public Long Length():返回由此File表示的文件的长度。
获取的是构造方法指定的文件的大小,以字节为单位
注意:文件夹是没有大小概念的,不能获取文件夹的大小
如果构造方法中给出的路径不存在,那么Length方法返回0
*/
private static void show04(){
File f1 = new File("C:\\Users\\CHPang\\Pictures\\Screenshots\\1.jpg");
long l1 = f1.length();
System.out.println(l1);
}
/*
public String getName():返回由此File表示的文件或目录的名称。
获取的就是构造方法传递路径的结尾部分(文件/文件夹)
*/
public static void show03(){
File f1 = new File("C:\\t430\\java\\code\\heima\\a.txt");
String name1 = f1.getName();
System.out.println(name1);
File f2 = new File("C:\\t430\\java\\code\\heima");
String name2 = f2.getName();
System.out.println(name2);
}
/*
public String getPath():将此File转换为路径名字符串。
获取的构造方法中传递的路径
*/
public static void show02(){
File f1 = new File("C:\\t430\\java\\code\\heima\\a.txt");
File f2 = new File("a.txt");
String path1 = f1.getPath();
String path2 = f2.getPath();
System.out.println(path1);
System.out.println(path2);
}
private static void show01(){
File f1 = new File("C:\\t430\\java\\code\\heima\\a.txt");
String absolutePath1 = f1.getAbsolutePath();
System.out.println(absolutePath1);
File f2 = new File("a.txt");
String absolutePath2 = f2.getAbsolutePath();
System.out.println(absolutePath2);
}
}
File类判断功能
package file.Demo01;
import java.io.File;
/*
File判断功能的方法
public boolean exists():此File表示的文件或目录是否实际存在。
public boolean isDirectory():此File表示的是否为目录。
public boolean isFile():此File表示的是否为文件。
*/
public class Demo03 {
public static void main(String[] args) {
show01();
show02();
}
/*
public boolean exists():此File表示的文件或目录是否实际存在。
用于判断构造方法中的路径是否存在
存在:true不存在:false
*/
private static void show01(){
File f1 = new File("C:\\t430\\java\\code\\heima");
File f2 = new File("C:\\t430\\java\\code\\hei");
File f3 = new File("C:src");//相对路径
File f4 = new File("C:1.txt");//相对路径
System.out.println(f1.exists());
System.out.println(f2.exists());
System.out.println(f3.exists());
System.out.println(f4.exists());
}
/*
public boolean isDirectory():此File表示的是否为目录。
用于判断构造方法中给定的路径是否以文件夹结尾
是:true
否:false
public boolean isFile():此File表示的是否为文件。
用于判断构造方法中给定的路径是否以文件结尾
是:true否:false
注意:
电脑的硬盘中只有文件/文件夹,两个方法是互斥
这两个方法使用前提,路径必须是存在的,否则都返回false
*/
public static void show02(){
File f1 = new File("C:\\t430\\java\\code\\hei");
//不存在,没必要获取
if(f1.exists()){
System.out.println(f1.isDirectory());
System.out.println(f1.isFile());
}
File f2 = new File("C:\\\\t430\\\\java\\\\code\\\\heima");
if (f2.exists()){
System.out.println(f2.isFile());
System.out.println(f2.isDirectory());
}
}
}
File类创建删除功能
package file.Demo01;
import java.io.File;
import java.io.IOException;
/*
File类创建删除功能的方法
public boolean createNewFile():当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
public boolean delete():删除由此File表示的文件或目录。
public boolean mkdir():创建由此File表示的目录。
public boolean mkdirs():创建由此File表示的目录,包括任何必需但不存在的父目录。
*/
public class Demo04 {
public static void main(String[] args) throws IOException {
show01();//创建文件
show02();//创建文件夹
show03();//删除文件夹
}
/*
public boolean createNewFile():当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
创建文件的路径和名称在构造方法中给出(构造方法的参数)
返回值:布尔值
true:文件不存在,创建文件,返回true
false:文件存在,不会创建,返回false
注意:
1.此方法只能创建文件,不能创建文件夹
2.创建文件的路径必须存在,否则会抛出异常
public boolean createNewFile()throws IOException
createNewFile声明抛出了IOException,我们调用这个方法,就必须的处理这个异常,要么throws,要么trycatch
*/
private static void show01() throws IOException {
File f1 = new File("C:\\t430\\java\\anything\\1.txt");
boolean b1 = f1.createNewFile();
System.out.println(b1);
File f2 = new File("C:\\t430\\java\\anything\\2.txt");
System.out.println(f2.createNewFile());
}
/*
public boolean mkdir():创建单级文件夹
public boolean mkdirs():创建多级文件夹
创建文件夹的路径和名称在构造方法中给出(构造方法的参数)
返回值:布尔值
true:文件夹不存在,创建文件夹,返回true
false:文件夹存在,不会创建,返回false;构造方法中给出的路径不存在返回false
注意:
1.此方法只能创建文件,不能创建文件夹
2.创建文件的路径必须存在,否则会抛出异常
*/
private static void show02(){
File f1 = new File("C:\\t430\\java\\anything\\aaa");
boolean b1 = f1.mkdir();
System.out.println("b1:"+b1);
File f2 = new File("C:\\t430\\java\\anything\\111\\222");
f2.mkdirs();
}
/*
public boolean delete():删除由此File表示的文件或目录。
此方法,可以删除构造方法路径中给出的文件/文件夹
返回值:布尔值
true:文件/文件夹删除成功,返回true
false:文件夹中有内容,不会删除返回false;构造方法中路径不存在false
注意:delete方法是直接在硬盘删除文件/文件夹,不走回收站,删除要谨慎
*/
public static void show03(){
File f1 = new File("C:\\t430\\java\\anything\\1.txt");
boolean b1 = f1.delete();
System.out.println(b1);
}
}
file类遍历目录
package file.Demo01;
import java.io.File;
/*
File类遍历(文件夹)目录功能
public String[]list():返回一个String数组,表示该File目录中的所有子文件或目录。
public File[]listFiles():返回一个File数组,表示该File目录中的所有的子文件或目录。
注意:
list方法和ListFiles方法遍历的是构造方法中给出的目录
如果构造方法中给出的目录的路径不存在,会抛出空指针异常
如果构造方法中给出的路径不是一个目录,也会抛出空指针异常
*/
public class Demo05 {
public static void main(String[] args) {
show01();
}
/*
public String[]list():返回一个String数组,表示该File目录中的所有子文件或目录。
遍历构造方法中给出的目录,会获取目录中所有文件/文件夹的名称,把获取到的多个名称存储到一个String类型的数组中
*/
private static void show01(){
File file = new File("C:\\t430\\java\\anything");
String[] arr = file.list();
for (String filename : arr) {
System.out.println(filename);
}
}
}
02 递归
概念
package file.digui;
/*
递归:方法自己调用自己
递归的分类:
递归分为两种,直接递归和间接递归。
直接递归称为方法自身调用自己。
间接递归可以A方法调用B方法,B方法调用c方法,c方法调用A方法。
注意事项:
递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。
在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。
构造方法,禁止递归
递归的使用前提:
当调用方法的时候,方法的主体不变,每次调用方法的参数不同,可以使用递归
*/
public class Demo01 {
public static void main(String[] args) {
// a();
b(1);
}
/*
在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。
*/
private static void b(int i) {
System.out.println(i);
if (i==10000){
return;//结束方法
}
b(++i);
}
/*
递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。
Exception in thread"main"java.Lang.StackoverflowError
*/
// private static void a() {
// System.out.println("a方法");
// a();
// }
}
练习 : 计算1-n的和
package file.digui;
public class Demo02 {
public static void main(String[] args) {
int s = sum(100);
System.out.println(s);
}
/*
定义方法,使用递归算和
递归结束的条件,获取1的时候结束
目的:获取到下一个被加的数字
*/
public static int sum(int n){
if (n==1){
return 1;
}
return n + sum(n-1);
}
}
递归打印多级目录
package file.digui;
import java.io.File;
public class Demo03 {
public static void main(String[] args) {
File file = new File("C:\\t430\\java\\anything");
getAllFile(file);
}
private static void getAllFile(File dir) {
System.out.println(dir);//打印被遍历的文件夹
File[] files = dir.listFiles();
for (File f:files){
//对遍历得到的File对象f进行判断,判断是否是文件夹
if (f.isDirectory()){
//f是一个文件夹,则继续遍历这个文件夹
//我们发现getALLFile方法就是传递文件夹,遍历文件夹的方法
//所以直接调用getAllFile方法即可:递归(自己调用自己)
getAllFile(f);
}else {
System.out.println(f);
}
}
}
}
综合案例文件搜索
package file.digui;
import java.io.File;
import java.util.Locale;
//只要.jpg结尾的文件
public class Demo04 {
public static void main(String[] args) {
File file = new File("C:\\t430\\java\\anything");
getAllFile(file);
}
private static void getAllFile(File dir) {
// System.out.println(dir);//打印被遍历的文件夹
File[] files = dir.listFiles();
for (File f:files){
//对遍历得到的File对象f进行判断,判断是否是文件夹
if (f.isDirectory()){
//f是一个文件夹,则继续遍历这个文件夹
//我们发现getALLFile方法就是传递文件夹,遍历文件夹的方法
//所以直接调用getAllFile方法即可:递归(自己调用自己)
getAllFile(f);
}else {
//只要.jpg结尾的文件
//把File对象f转换为字符串对象
// String name = f.getName();
// String path = f.getPath();
String s = f.toString();
//把字符串改为小写
s = s.toLowerCase();
//调用String类中的方法endswith,判断是不是以。java结尾
boolean b = s.endsWith(".jpg");
//如果是java结尾输出
if (b){
System.out.println(f);
}
}
}
}
}
对上一个例子进行简化
package file.digui;
import java.io.File;
import java.util.Locale;
public class Demo05 {
public static void main(String[] args) {
File file = new File("C:\\t430\\java\\anything");
getAllFile(file);
}
private static void getAllFile(File dir) {
// System.out.println(dir);//打印被遍历的文件夹
File[] files = dir.listFiles();
for (File f:files){
if (f.isDirectory()){
getAllFile(f);
}else {
if (f.getName().toLowerCase().endsWith(".jpg")){
System.out.println(f);
}
}
}
}
}
03 过滤器

package file.过滤器;
import java.io.File;
import java.io.FileFilter;
//创建过滤器FileFilter的实现类,重写过滤方法accept,定义过滤规则
public class FileFilterImpl implements FileFilter {
@Override
public boolean accept(File pathname) {
//如果pathname是一个文件夹,返回true,继续遍历这个文件夹
if (pathname.isDirectory()){
return true;
}
return pathname.getName().toLowerCase().endsWith(".jpg");
}
}
package file.过滤器;
import java.io.File;
/*
我们可以便用过滤器来实现
在File类中有两个和ListFiles重载的方法,方法的参数传递的就是过滤器
File[]listFiles(FileFilter filter)
java.io.FileFilter接口:用于抽象路径名(File对象)的过滤器。
作用:用来过滤文件(File对象)
抽象方法:用来过滤文件的方法
boolean accept(File pathname)测试指定抽象路径名是否应该包含在某个路径名列表中。
参数:
File pathname:使用ListFiles方法遍历目录,得到的每一个文件对象
File[]listFiles(FilenameFilter filter)
java.io.FilenameFilter接口:实现此接口的类实例可用于过滤器文件名。
作用:用于过滤文件名称
抽象方法:用来过滤文件的方法
boolean accept(File dir,String name)测试指定文件是否应该包含在某一文件列表中。
参数:
File dir:构造方法中传递的被遍历的目录
String name:使用ListFiles方法遍历目录,获取的每一个文件/文件夹的名称
注意:两个过滤器接口是没有实现类的,需要我们自己写实现类,重写过滤的方法accept,在方法中自己定义过滤的规则
*/
public class Demo01 {
public static void main(String[] args) {
File file = new File("C:\\t430\\java\\anything");
getAllFile(file);
}
private static void getAllFile(File dir) {
File[] files = dir.listFiles(new FileFilterImpl());//传递了一个过滤器
for (File f:files){
//对遍历得到的File对象f进行判断,判断是否是文件夹
if (f.isDirectory()){
//f是一个文件夹,则继续遍历这个文件夹
//我们发现getALLFile方法就是传递文件夹,遍历文件夹的方法
//所以直接调用getAllFile方法即可:递归(自己调用自己)
getAllFile(f);
}else {
System.out.println(f);
}
}
}
}
使用内部类实现上述问题
package file.过滤器;
import java.io.File;
import java.io.FileFilter;
public class Demo02 {
public static void main(String[] args) {
File file = new File("C:\\t430\\java\\anything");
getAllFile(file);
}
private static void getAllFile(File dir) {
//传递过滤器对象 使用匿名内部类
File[] files = dir.listFiles(new FileFilter() {
public boolean accept(File pathname) {
return pathname.isDirectory() || pathname.getName().toLowerCase().endsWith(".jpg");
}
});
for (File f:files){
//对遍历得到的File对象f进行判断,判断是否是文件夹
if (f.isDirectory()){
//f是一个文件夹,则继续遍历这个文件夹
//我们发现getALLFile方法就是传递文件夹,遍历文件夹的方法
//所以直接调用getAllFile方法即可:递归(自己调用自己)
getAllFile(f);
}else {
System.out.println(f);
}
}
}
}
另一种内部类实现方法
package file.过滤器;
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
public class Demo02 {
public static void main(String[] args) {
File file = new File("C:\\t430\\java\\anything");
getAllFile(file);
}
private static void getAllFile(File dir) {
File[] files = dir.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return new File(dir,name).isDirectory() || name.toLowerCase().endsWith(".jpg");
}
});
for (File f:files){
//对遍历得到的File对象f进行判断,判断是否是文件夹
if (f.isDirectory()){
//f是一个文件夹,则继续遍历这个文件夹
//我们发现getALLFile方法就是传递文件夹,遍历文件夹的方法
//所以直接调用getAllFile方法即可:递归(自己调用自己)
getAllFile(f);
}else {
System.out.println(f);
}
}
}
}
注意:这两个简化方法都可以用lamda表达式进行优化
04 IO字节流
一切皆为字节
字节输出并写入数据到文件
package file.字节流;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
java.io.Outputstream:字节输出流
此抽象类是表示输出字节流的所有类的超类。
定义了一些子类共性的成员方法:
public void close():关闭此输出流并释放与此流相关联的任何系统资源。
public void flush():刷新此输出流并强制任何缓冲的输出字节被写出。
public void write(byte[]b):将b.Length字节从指定的字节数组写入此输出流。
public void write(byte[]b,int off,int Len):从指定的字节数组写入Len字节,从偏移量 off开始输出到此输出流。
public abstract void write(int b):将指定的字节输出流。
java.io.FileOutputstream extends OutputStream
FileOutputStream:文件字节输出流
作用:把内存中的数据写入到硬盘的文件中
构造方法:
Fileoutputstream(String name)创建一个向具有指定名称的文件中写入数据的输出文件流。
FileOutputStream(File file)创建一个向指定File 对象表示的文件中写入数据的文件输出流。
参数:写入数据的目的
string name:目的地是一个文件的路径
File file:目的地是一个文件
构造方法的作用:
1.创建一个FileOutputStream对象
2.会根据构造方法中传递的文件/文件路径,创建一个空的文件
3.会把FileOutputStream对象指向创建好的文件
写入数据的原理:
java程序-->JVM(java虚拟机)-->OS(操作系统)-->OS调用写数据的方法-->把数据写入到文件中
字节输出流的使用步骤(重点):
1.创建一个FileOutputStream对象,构造方法中传递写入数据的目的地
2.调用FileOutputStream对象中的方法write,把数据写入到文件中
3.释放资源(流使用会占用一定的内存,使用完毕要把内存清空,提供程序的效率)
*/
public class Demo01 {
public static void main(String[] args) throws IOException {
// 1.创建一个FileOutputStream对象,构造方法中传递写入数据的目的地
FileOutputStream fos = new FileOutputStream("C:\\t430\\java\\anything\\a.txt");
//2.调用FileOutputStream对象中的方法write,把数据写入到文件中
// public abstract void write(int b):将指定的字节输出流。
fos.write(97);
// 3.释放资源(流使用会占用一定的内存,使用完毕要把内存清空,提供程序的效率)
fos.close();
}
}
写多个字节
package file.字节流;
import javax.imageio.IIOException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Arrays;
/*
public void write(byte[]b):将b.Length字节从指定的字节数组写入此输出流。
public void write(byte[]b,int off,int Len):从指定的字节数组写入Len字节,从偏移量 off开始输出到此输出流。
*/
public class Demo02 {
public static void main(String[] args) throws IOException {
//创建FileOutputStream对象,构造方法中绑定要写入数据的目的地,
FileOutputStream fos = new FileOutputStream(new File("C:\\t430\\java\\anything\\b.txt"));
//调用FileOutputStream对象中的方法write,把数据写入到文件中
//在文件中显示100,写个字节
fos.write(49);
fos.write(48);
fos.write(48);
/*
public void write(byte[]b):将b.Length字节从指定的字节数组写入此输出流。
一次写多个字节:
如果写的第一个字节是正数(0-127),那么显示的时候会查询ASCII表
如果写的第一个字节是负数,那第一个字节会和第二个字节,两个字节组成一个中文显示,查询系统默认码表(GBK)
*/
byte[] bytes = {65,66,67,68,69};
//byte[] bytes = {-65,-66,-67,68,69};比较特殊
fos.write(bytes);
/*
public void write(byte[]b,int off,int len):把字节数组的一部分写入到文件中
int off:数组的开始索引
int Len:写几个字节
*/
fos.write(bytes,1,2);
/*
写入字符的方法:可以使用String类中的方法把字符串,转换为字节数组
byte[]getBytes()把字符串转换为字节数组
*/
byte[] bytes1 = "你好".getBytes();
System.out.println(Arrays.toString(bytes1)); //[-28, -67, -96, -27, -91, -67]
fos.write(bytes1);
//释放资源
fos.close();
}
}
输出字节流的续写和换行写
package file.字节流;
import java.io.FileOutputStream;
import java.io.IOException;
/*
追加写/续写:使用两个参数的构造方法
FileOutputStream(String name,boolean append)创建一个向具有指定name的文件中写入数据的输出文件流。
FileOutputStream(File file,boolean append)创建一个向指定File 对象表示的文件中写入数据的文件输出流。
参数:
String name,File file:S入数据的目的地
boolean append:追加写开关
true:创建对象不会覆盖源文件,继续在文件的末尾追加写数据
false:创建一个 新文件,覆盖源文件
写换行:写换行符号
windows:Irln
Linux:/n
mac:/r
*/
public class Demo03 {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("C:\\t430\\java\\anything\\c.txt",true);
for (int i = 0; i < 10; i++) {
fos.write("你好".getBytes());
fos.write("\r\n".getBytes());
}
fos.close();
}
}
字节输入流_InputStream类&Fil,来读取字节数据
package file.字节流;
import java.io.FileInputStream;
import java.io.IOException;
/*
java.io.InputStream:字节输入流
此抽象类是表示字节输入流的所有类的超类。
定义了所有子类共性的方法:
int read()从输入流中读取数据的下一个字节。
int read(byte[]b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中。
void close()关闭此输入流并释放与该流关联的所有系统资源。
java.io.FileInputStream extends InputStream
FileInputStream:文件字节输入流
作用:把硬盘文件中的数据,读取到内存中使用
构造方法:
FileInputStream(String name)
FileInputStream(File file)
参数:读取文件的数据源
String name:文件的路径
File file:文件
构造方法的作用:
1.会创建一个FileInputStream对象
2.会把FileInputStream对象指定构造方法中要读取的文件
字节输入流的使用步骤(重点):
1.创建FileInputStream对象,构造方法中绑定要读取的数据源
2.使用FileInputStream对象中的方法read,读取文件
3.释放资源
*/
public class Demo04 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("C:\\t430\\java\\anything\\a.txt");
// int len = fis.read();
// System.out.println(len);
//
// int len1 = fis.read();
// System.out.println(len1);
// int len2 = fis.read();
// System.out.println(len2);
// int len3 = fis.read();
// System.out.println(len3);
/*
发现以上读取文件是一个重复的过程,
所以可以使用循环优化
不知道文件中有多少字节,使用while循环while循环结束条件,读取到-1的时候结束
*/
int len = 0;//记录读取到的字节
while ((len = fis.read())!=-1){
System.out.println(len);
System.out.println((char)len);
}
fis.close();
}
}
字节输入流一次读取多个字节
package file.字节流;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
/*
字节输入流一次读取多个字节的方法:
int read(byte[]b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中。
明确两件事情:
1.方法的参数byte[]的作用?
2.方法的返回值int是什么?
String类的构造方法
string(byte[]bytes):把字节数组转换为字符串
string(byte[]bytes,int offset,int length)把字节数组的一部分转换为字符串 offset:数组的开始索引Length:转换的字节个数
*/
public class Demo05 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("C:\\t430\\java\\anything\\b.txt");
byte[] bytes = new byte[2];
// int len = fis.read(bytes);
// System.out.println(len);//2
// //System.out.println(Arrays.toString(bytes));//[65,66]
// System.out.println(new String(bytes));
//
// len = fis.read(bytes);
// System.out.println(len);//2
// System.out.println(new String(bytes));
//
// len = fis.read(bytes);
// System.out.println(len);//2
// System.out.println(new String(bytes));
//循环
byte[] bytes1 = new byte[1024];//存储读取道德多个字节
int len = 0;
while ((len = fis.read(bytes1))!=-1){
System.out.println(new String(bytes1));//一i那位长度1024,剩余的就都是空格
System.out.println(new String(bytes1,0,len));//方法二,结果正常
}
//释放资源
fis.close();
}
}
一次一个字节与一次多个字节的原理![image-20220317232209443]()

练习: 文件复制

package file.字节流;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
文件复制练习:一读一写
明确:
数据源:c:111.jpg
数据的目的地:d:111.jpg
文件复制的步骤:
1.创建一个字节输入流对象,构造方法中绑定要读取的数据源
2.创建一个字节输出流对象,构造方法中绑定要写入的目的地
3.使用字节输入流对象中的方法read读取文件
4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中
5·释放资源
*/
public class Demo06 {
public static void main(String[] args) throws IOException {
//1.创建一个字节输入流对象,构造方法中绑定要读取的数据源
FileInputStream fis = new FileInputStream("C:\\t430\\java\\anything\\a.txt");
//2.创建一个字节输出流对象,构造方法中绑定要写入的目的地
FileOutputStream fos = new FileOutputStream("C:\\t430\\java\\anything1\\a.txt");
// 3.使用字节输入流对象中的方法read读取文件
// int len = 0;
// while ((len = fis.read())!=-1){
// // 4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中
// fos.write(len);
// }
//一次读取一个字节太慢了,使用数组比较快
byte[] bytes = new byte[1024];
//3.使用字节输入流对象中的read读取文件
int len = 0;
while ((len = fis.read(bytes))!=-1) {
// 4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中
fos.write(bytes,0,len);
}
//5·释放资源 先关写的,后关读的。因为写完了肯定读完了
fos.close();
fis.close();
}
}
使用字节流读取中文
使用字节流读取中文文件 1个中文 GBK:占用两个字节 UTF-8:占用3个字节
05字符流
字符输入流
package file.字符流;
import java.io.FileReader;
import java.io.IOException;
/*
java.io.Reader:字符输入流,是字符输入流的最顶层的父类,定义了一些共性的成员方法,是一个抽象类
共性的成员方法:
int read()读取单个字符并返回。
int read(char[]cbuf)一次读取多个字符,将字符读入数组。
void close()关闭该流并释放与之关联的所有资源。
java.io.FileReader extends InputStreamReader extends Reader
FileReader:文件字符输入流
作用:把硬盘文件中的数据以字符的方式读取到内存中
构造方法:
FileReader(String fileName)
FileReader(File file)
参数:读取文件的数据源
String fileName:文件的径
File file:一个文件
FileReader构造方法的作用:
1.创建一个FileReader对象
2.会把FileReader对象指向要读取的文件
字符输入流的使用步骤:
1.创建FiLeReader对象,构造方法中绑定要读取的数据源
2.使用FileReader对象中的方法read读取文件3,释放资源
*/
public class Demo01 {
public static void main(String[] args) throws IOException {
// 1.创建FiLeReader对象,构造方法中绑定要读取的数据源
FileReader fr = new FileReader("C:\\t430\\java\\anything\\b.txt");
// 2.使用FileReader对象中的方法read读取文件3,释放资源
// int len = 0;
// while ((len = fr.read())!=-1){
// System.out.print((char)len);
// }
// int read(char[]cbuf)一次读取多个字符,将字符读入数组
char[] cs = new char[1024];//存储读取到的多个字符
int len = 0;//记录的是每次读取的字符个数
while ((len = fr.read(cs))!=-1){
/*
string类的构造方法
string(char[]value)把字符数组转换为字符串
String(char[]value,int offset,int count)把字符数组的一部分转换为字符串 offset数组的开始索引count转换的个数
*/
System.out.println(new String(cs,0,len));
}
fr.close();
}
}
字符输出流
package file.字符流;
import java.io.FileWriter;
import java.io.IOException;
/*
java.io.Writer:字符输出流,是所有字符输出流的最顶层的父类,是一个抽象类
共性的成员方法:
-void write(int c)写入单个字符。
-void write(char[]cbuf)写入字符数组。
-abstract void write(char[]cbuf,int off,int Len)写入字符数组的某一部分,off数组的开始索引,Len写的字符个数。
-void write(String str)写入字符。
-void write(String str,int off,int Len)写入字符串的某一部分,off字符串的开始索引,Len写的字符个数。
-void flush()刷新该流的缓冲。
-void close()关闭此流,但要先刷新它。
java.io.Filewriter extends OutputStreamwriter extends writer
Filewriter:文件字符输出流
作用:把内存中字符数据写入到文件中
构造方法:
Filewriter(File file)根据给定的File 对象构造一个Filewriter对象。
Filewriter(String fileName)根据给定的文件名构造一个Filewriter对象。
参数:写入数据的目的地
string fileName:文件的路径
File file:是一个文件
构造方法的作用:
1.会创建一个FiLewriter对象
2.会根据构造方法中传递的文件/文件的路径,创建文件
3.会把Filewriter对象指向创建好的文件
字符输出流的使用步骤(重点):
1.创建Filewriter对象,构造方法中绑定要写入数据的目的地,
2.使用Filewriter中的方法write,把数据写入到内存缓冲区中(字符转换为字节的过程)
3.使用Filewriter中的方法flush,把内存缓冲区中的数据,刷新到文件中
4.释放资源(会先把内存缓冲区中的数据刷新到文件中)
*/
public class Demo02 {
public static void main(String[] args) throws IOException {
//1.创建Filewriter对象,构造方法中绑定要写入数据的目的地,
FileWriter fw = new FileWriter("C:\\t430\\java\\anything\\d.txt");
//2.使用Filewriter中的方法write,把数据写入到内存缓冲区中(字符转换为字节的过程)
//void write(int c) 写入单个字符
fw.write(97);
//3.使用Filewriter中的方法flush,把内存缓冲区中的数据,刷新到文件中
fw.flush();
fw.close();
}
}
flush方法和close方法的区别
flush:刷新缓冲区,流对象可以继续使用。 close:先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。
package file.字符流;
import java.io.FileWriter;
import java.io.IOException;
public class Demo03 {
public static void main(String[] args) throws IOException {
//1.创建Filewriter对象,构造方法中绑定要写入数据的目的地,
FileWriter fw = new FileWriter("C:\\t430\\java\\anything\\e.txt");
//2.使用Filewriter中的方法write,把数据写入到内存缓冲区中(字符转换为字节的过程)
//void write(int c) 写入单个字符
fw.write(97);
//3.使用Filewriter中的方法flush,把内存缓冲区中的数据,刷新到文件中
fw.flush();
//刷新之后流可以继续使用
fw.write(98);
fw.close();
//close之后流就结束了,在write就会报错
// fw.write(99);
}
}
字符流写数据的其他方法
package file.字符流;
/*
字符输出流写数据的其他方法:
-void write(char[]cbuf)写入字符数组。
-abstract void write(char[]cbuf,int off,int len)写入字符数组的某一部分,off数组的开始索引,Len写的字符个数。
-void write(String str)写入字符串。
-void write(String str,int off,int Len)写入字符串的某一部分,off字符串的开始索引,Len写的字符个数。
*/
import java.io.FileWriter;
import java.io.IOException;
public class Demo04 {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("C:\\t430\\java\\anything\\f.txt");
// -void write(char[]cbuf)写入字符数组。
char[] cs = {'a','b','c','d','e'};
fw.write(cs);//abcd
//-abstract void write(char[]cbuf,int off,int len)写入字符数组的某一部分,off数组的开
fw.write(cs,1,3);//bcd
//void write(String str)写入字符串。
fw.write("牛逼666");
//void write(String str,int off,int Len)写入字符串的某一部分
fw.write("卧槽牛逼啊",2,3);
fw.close();
}
}
续写和换行
package file.字符流;
import java.io.FileWriter;
import java.io.IOException;
/*
续写和换行
续写,追加写:使用两个参数的构造方法
Filewriter(String fileName,boolean append)
Filewriter(File file,boolean append)
参数:
String fileName,File file:写入数据的目的地换行:换行符号
boolean append:续写开关 true:不会创建新的文件覆盖源文件,可以续写;false:创建新的文件覆盖源文件
windows:\r\n Linux:/n mac:/r
*/
public class Demo05 {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("C:\\t430\\java\\anything\\g.txt");
for (int i = 0; i < 10; i++) {
fw.write("helloworld"+i+"\r\n");
}
fw.close();
}
}
使用try catch finally处理流中的异
jdk1.7之前
package file.字符流;
import java.io.FileWriter;
import java.io.IOException;
/*
在jdk1.7之前使用try catch finally处理流中的异常
格式:
try{
可能会产出异常的代码
}catch(异常类变量变量名){
异常的处理逻辑
}finally{
一定会指定的代码
资源释放
}
*/
public class Demo06 {
public static void main(String[] args) {
//提高变量fw的 作用域,让finally可以使用
//变量在定义的时候可以没有值,但在使用的时候必须有值
//fw = new FileWriter("C:\\t430\\java\\anything\\g.txt");执行失败,fw没有值,fw.close报错
FileWriter fw = null;
try {
//可能会产生的异常代码
fw = new FileWriter("C:\\t430\\java\\anything\\g.txt",true);
for (int i = 0; i < 10; i++) {
fw.write("helloworld"+i+"\r\n");
}
}catch (IOException e){
//异常的处理逻辑
System.out.println("e");
}finally {
//一定会执行的代码
//创建对象失败了,fw的默认值是null,null是不能调用方法的,会抛出nullPointException,需要增加一个判断,不是null再把资源释放
if (fw!=null){
try {
//fw.close方法声明了IOexception异常,所以我们要处理这个异常对象,要么throws,要么try catch
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
jdk1.7
JDK7的新特性
在try的后边可以增加一个(),在括号中可以定义流对象
那么这个流对象的作用域就在try中有效
try中的代码执行完毕,会自动把流对象释放,不用写finally
格式:
try(定义流对象;定义流对象...){
可能会产出异常的代码
}catch(异常类变量变量名){
异常的处理逻辑
}
jdk9
06 Properties集合
使用Properties集合存储数据,遍历
package file.Properties集合;
import java.util.Properties;
import java.util.Set;
/*
java.util.Properties集合 extends Hashtable<k,v> impLements Map<k,v>
Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。
Properties集合是一个唯一和IO流相结合的集合
可以使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储
可以使用Properties集合中的方法Load,把硬盘中保存的文件(键值对),读取到集合中使用
属性列表中每个键及其对应值都是一个字符串。
Properties集合是一个双列集合,key和value默认都是字符串
*/
public class Demo01 {
public static void main(String[] args) {
show01();
}
/*
使用Properties集合存储数据,遍历取出Properties集合中的数据
Properties集合是一个双列集合,key和value默认都是字符串
Properties集合有一些操作字符串的特有方法
Object setProperty(String key,String value)用Hashtable 的方法 put
String getProperty(String key)通过key找到value值,此方法相当于Map集合中的get(key)方法
Set<string> stringPropertyNames()返回此属性列表中的键集,其中该键及其对应值是字符串,此方法相当于Map集合中的keyset方法
*/
private static void show01() {
//创建properties集合对象
Properties prop = new Properties();
//使用setProperty往集合种添加对象
prop.setProperty("赵丽颖","168");
prop.setProperty("迪丽热巴","165");
prop.setProperty("古力娜扎","160");
//使用stringPropertyNames()把Properties集合中的键取出,存储到一个Set集合中
Set<String> set = prop.stringPropertyNames();
//遍历Set集合,取出properties集合的每一键
for (String key:set){
//使用getProperrty方法通过key获取value
String value = prop.getProperty(key);
System.out.println(key+"="+value);
}
}
}
Properties集合中的store方法
package file.Properties集合;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;
/*
java.util.Properties集合 extends Hashtable<k,v> impLements Map<k,v>
Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。
Properties集合是一个唯一和IO流相结合的集合
可以使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储
可以使用Properties集合中的方法Load,把硬盘中保存的文件(键值对),读取到集合中使用
属性列表中每个键及其对应值都是一个字符串。
Properties集合是一个双列集合,key和value默认都是字符串
*/
public class Demo01 {
public static void main(String[] args) throws IOException {
show02();
}
/*
可以使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储
void store(OutputStream out,String comments)
void store(writer writer,String comments)
参数:
OutputStream out:字节输出流,不能写入中文
Writer writer:字符输出流,可以写中文
String comments:注释,用来解释说明保存的文件是做什么用的
不能使用中文,会产生乱码,默认是Unicode编码
一般使用"空字符串
使用步骤:
1.创建Properties集合对象,添加数据
2.创建字节输出流/字符输出流对象,构造方法中绑定要输出的目的地,
3.使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储
4.释放资源
*/
private static void show02() throws IOException {
//1.创建Properties集合对象,添加数据
Properties prop = new Properties();
prop.setProperty("赵丽颖","168");
prop.setProperty("迪丽热巴","165");
prop.setProperty("古力娜扎","160");
//2.创建字节输出流/字符输出流对象,构造方法中绑定要输出的目的地,
FileWriter fw = new FileWriter("C:\\t430\\java\\anything\\prop.txt");
//3.使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储
prop.store(fw,"save data");
fw.close();
//用字节流
// prop.store(new FileOutputStream("C:\\t430\\java\\anything\\prop2.txt"),""); //全是乱码
//字符流可以写中文,字节流不可以写中文
}
}
load方法
package file.Properties集合;
import java.io.*;
import java.util.Properties;
import java.util.Set;
/*
java.util.Properties集合 extends Hashtable<k,v> impLements Map<k,v>
Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。
Properties集合是一个唯一和IO流相结合的集合
可以使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储
可以使用Properties集合中的方法Load,把硬盘中保存的文件(键值对),读取到集合中使用
属性列表中每个键及其对应值都是一个字符串。
Properties集合是一个双列集合,key和value默认都是字符串
*/
public class Demo01 {
public static void main(String[] args) throws IOException {
show03();
}
/*
可以使用Properties集合中的方法Load,把硬盘中保存的文件(键值对),读取到集合中使用
void load(InputStream inStream)
void load(Reader reader)
参数:
Inputstream inStream:字节输入流,不能读取含有中文的键值对
Reader reader:字符输入流,能读取含有中文的键值对
使用步骤:
1.创建Properties集合对象
2.使用Properties集合对象中的方法Load读取保存键值对的文件
3.遍历Properties集合
注意:
1.存储键值对的文件中,键与值默认的连接符号可以使用=,空格(其他符号)
2.存储键值对的文件中,可以使用#进行注释,被注释的键值对不会再被读取
3.存储键值对的文件中,键与值默认都是字符串,不用再加引号
*/
private static void show03() throws IOException {
//1.创建Properties集合对象
Properties prop = new Properties();
// 2.使用Properties集合对象中的方法Load读取保存键值对的文件
prop.load(new FileReader("C:\\t430\\java\\anything\\prop.txt"));//if use byte IOstream,会乱码
//3.遍历Properties集合
Set<String> set = prop.stringPropertyNames();
for (String key: set){
String value = prop.getProperty(key);
System.out.println(key+"="+value);
}
}
}
07 缓冲流
原理

BufferedOutputStream字节缓冲输出流
package file.缓冲流;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/*
java.io.Bufferedoutputstream extends OutputStream
BufferedOutputStream:字节缓冲输出流
继承自父类的共性成员方法:
-public void close():关闭此输出流并释放与此流相关联的任何系统资源。
-public void flush():刷新此输出流并强制任何缓冲的输出字节被写出。
-public void write(byte[]b):将b.Length字节从指定的字节数组写入此输出流。
-public void write(byte[]b,int off,int Len):从指定的字节数组写入Len字节,从偏移量 off开始输出到此输出流。
-public abstract void write(int b):将指定的字节输出流。
构造方法:
BufferedOutputStream(OutputStream out)创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
BufferedOutputStream(OutputStream out,int size)创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层
参数:
OutputStream out:字节输出流
我们可以传递FileOutputStream,缓冲流会给FileOutputStream增加一个缓冲区,提高FileOutputStream的写入效率
int size:指定缓冲流内部缓冲区的大小,不指定默认
使用步骤(重点)
1.创建FileOutputStream对象,构造方法中绑定要输出的目的地
2.创建BufferedOutputStream对象,构造方法中传递FileOutputStream对象对象,提高FileOutputStream对象效率
3.使用BufferedOutputStream对象中的方法write,把数据写入到内部缓冲区中
4.使用BufferedOutputStream对象中的方法flush,把内部缓冲区中的数据,刷新到文件中
5.释放资源(会先调用fLush方法刷新数据,第4部可以省略)
*/
public class Demo01 {
public static void main(String[] args) throws IOException {
//1.创建FileOutputStream对象,构造方法中绑定要输出的目的地
FileOutputStream fos = new FileOutputStream("C:\\t430\\java\\anything\\h.txt");
//2.创建BufferedOutputStream对象,构造方法中传递FileOutputStream对象对象,提高FileOutputStream对象效率
BufferedOutputStream bos = new BufferedOutputStream(fos);
//3.使用BufferedOutputStream对象中的方法write,把数据写入到内部缓冲区中
bos.write("把我的数据写入到内部缓冲区".getBytes());
//4.使用BufferedOutputStream对象中的方法flush,把内部缓冲区中的数据,刷新到文件中
bos.flush();
bos.close();
}
}
BufferedInputStream字节缓冲输入流
package file.缓冲流;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
java.io.BufferedInputstream extends InputStream
BufferedInputStream:字节缓冲输入流
继承自父类的成员方法:
int read()从输入流中读取数据的下一个字节。
int read(byte[]b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中。
void close()关闭此输入流并释放与该流关联的所有系统资源。
构造方法:
BufferedInputStream(InputStream in)创建-BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
BufferedInputStream(InputStream in,int size)创建具有指定缓冲区大小的BufferedInputStream并保存其参数,即输入流
参数:
Inputstream in:字节输入流
我们可以传递FileInputStream,缓冲流会给FileInputStream增加一个缓冲区,提高FileInputStream的读取效率
int size:指定缓冲流内部缓冲区的大小,不指定默认
使用步骤(重点):
1.创建FileInputStream对象,构造方法中绑定要读取的数据源
2.创建BufferedInputStream对象,构造方法中传递FileInputStream对象,提高FileInputStream对象的读取效率
3.使用BufferedInputStream对象中的方法read,读取文件
4.释放资源
*/
public class Demo02 {
public static void main(String[] args) throws IOException {
//1.创建FileInputStream对象,构造方法中绑定要读取的数据源
FileInputStream fis = new FileInputStream("C:\\t430\\java\\anything\\h.txt");
//2.创建BufferedInputStream对象,构造方法中传递FileInputStream对象,提高FileInputStream对象的读取效率
BufferedInputStream bis = new BufferedInputStream(fis);
/*
//3.使用BufferedInputStream对象中的方法read,读取文件
int len = 0;//记录每次读取到的字节
while ((len = bis.read())!=-1){
System.out.println(len);
}
*/
//更高效的读取方法
byte[] bytes = new byte[1024];//存储每次读取的数据
int len = 0;//记录每次读取的有效字节个数
while ((len = bis.read(bytes))!=-1){
System.out.println(new String(bytes,0,len));
}
bis.close();
}
}
缓冲流的效率测试
32ms vs 10ms
package file.缓冲流;
import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
import java.io.*;
/*
文件复制练习:一读一写
明确:
数据源:c:111.jpg
数据的目的地:d:111.jpg
文件复制的步骤:
1.创建字节缓冲输入流对象,构造方法中传递字节输入流
2.创建字节缓冲输出流对象,构造方法中传递字节输出流
3.使用字节缓冲输入流对象中的方法read,读取文件
4.使用字节缓冲输出流中的方法write,把读取的数据写入到内部缓冲区中
5·释放资源(会先把缓冲区中的数据,刷新到文件中)
*/
public class Demo03 {
public static void main(String[] args) throws IOException {
long s = System.currentTimeMillis();
//1.创建字节缓冲输入流对象,构造方法中传递字节输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("C:\\t430\\java\\anything\\1.jpg"));
//2.创建字节缓冲输出流对象,构造方法中传递字节输出流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:\\t430\\java\\anything1\\1.jpg"));
// 3.使用字节缓冲输入流对象中的方法read,读取文件
//一次读取一个字节写入一个字节的方式
// int len = 0;
// while ((len = bis.read())!=-1){
// bos.write(len);
// }
//使用数组
byte[] bytes = new byte[1024];
int len = 0;
while ((len = bis.read(bytes))!=-1){
bos.write(bytes,0,len);
}
bos.close();
bis.close();
long e = System.currentTimeMillis();
System.out.println("复制文件耗时"+(e-s)+"毫秒");
}
}
BufferedWriter 字符缓冲输出流
package file.缓冲流;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
/*
java.io.BufferedWriter extends writer
BufferedWriter:字符缓冲输出流
继承自父类的共性成员方法:
-void write(int c)写入单个字符。
-void write(char[] cbuf)写入字符数组。
-abstract void write(char[] cbuf,int off,int Len)写入字符数组的某一部分,off数组的开始索引,Len写的字符个数。
-void write(String str)写入字符。
-void write(String str,int off,int Len)写入字符串的某一部分,off字符串的开始索引,Len写的字符个数。
-void flush()刷新该流的缓冲。
-void close()关闭此流,但要先刷新它。
构造方法:
BufferedWriter(Writer out)创建一个使用默认大小输出缓冲区的缓冲字符输出流。
BufferedWriter(Writer out,int sz)创建一个使用给定大小输出缓冲区的新缓冲字符输出流。
参数:
Writer out:字符输出流
我们可以传递FileWriter,缓冲流会给FileWriter增加一个缓冲区,提高Filewriter的写入效率
int sz:指定缓冲区的大小,不写默认大小
特有的成员方法:
void newline()写入一个行分隔符。会根据不同的操作系统,获取不同的行分隔符换行:
换行符号
windows:\r\n
Linux:/n
mac:/r
使用步骤:
1.创建字符缓冲输出流对象,构造方法中传递字符输出流
2.调用字符缓冲输出流中的方法write,把数据写入到内存缓冲区中
3.调用字符缓冲输出流中的方法flush,把内存缓冲区中的数据,刷新到文件中
4.释放资源
*/
public class Demo04 {
public static void main(String[] args) throws IOException {
// 1.创建字符缓冲输出流对象,构造方法中传递字符输出流
BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\t430\\java\\anything1\\b.txt"));
//2.调用字符缓冲输出流中的方法write,把数据写入到内存缓冲区中
for (int i = 0; i < 10; i++) {
bw.write("传智播客");
//bw.write("\r\n");
bw.newLine();
}
//3.调用字符缓冲输出流中的方法flush,把内存缓冲区中的数据,刷新到文件中
bw.flush();
bw.close();
}
}
BufferedReader 字符缓冲输入流
package file.缓冲流;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/*
java.io.BufferedReader extends Reader继承自父类的共性成员方法:int read()读取单个字符并返回。
int read(char[]cbuf)一次读取多个字符,将字符读入数组。
void close()关闭该流并释放与之关联的所有资源。
构造方法:
BufferedReader(Reader in)创建一个使用默认大小输入缓冲区的缓冲字符输入流。
BufferedReader(Reader in,int sz)创建一个使用指定大小输入缓冲区的缓冲字符输入流。
参数:
Reader in:字符输入流
我们可以传递FileReader,缓冲流会给FileReader增加一个缓冲区,提高FiLeReader的读取效率
特有的成员方法:
String readline()读取一个文本行。读取一行数据
行的终止符号:通过下列字符之一即可认为某行已终止:换行('\n')、回车('\r')或回车后直接跟着换行(\r\n)
返回值:
包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回null
使用步骤:
1.创建字符缓冲输入流对象,构造方法中传递字符输入流
2.使用字符缓冲输入流对象中的方法read/readLine读取文本
3.释放资源
*/
public class Demo05 {
public static void main(String[] args) throws IOException {
//1.创建字符缓冲输入流对象,构造方法中传递字符输入流
BufferedReader br = new BufferedReader(new FileReader("C:\\t430\\java\\anything1\\b.txt"));
//2.使用字符缓冲输入流对象中的方法read/readLine读取文本
// String line = br.readLine();
// System.out.println(line);
//
// line = br.readLine();
// System.out.println(line);
//
// line = br.readLine();
// System.out.println(line);
//以上代码重复,,不知道有多少行数,结束条件为读取到null
String line;
while ((line = br.readLine())!=null){
System.out.println(line);
}
br.close();
}
}
对文本进行排序
08转换流
txt以ANSI格式存储,读取的时候出现了乱码
package file.转换流;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/*
FileReader可以读取IDE默认编码格式(UTF-8)的文件
FileReader读取系统默认编码(中文GBK)会产生乱码
*/
public class Demo01 {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("C:\\t430\\java\\anything1\\我是GBK格式的文本.txt");
int len = 0;
while ((len = fr.read())!=-1){
System.out.print((char)len);
}
fr.close();
}
}
转换流的原理


OutputStreamWriter
package file.转换流;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
/*
java.io.OutputStreamWriter extends Writer
OutputStreamWriter:是字符流通向字节流的桥梁:可使用指定的charset将要写入流中的字符编码成字节。(编码:把能看懂的变成看不懂)
继续自父类的共性成员方法:
-void write(int c)写入单个字符。
-void write(char[] cbuf)写入字符数组。
-abstract void write(char[] cbuf,int off,int Len)写入字符数组的某一部分,off数组的开始索引,Len写的字符个数。
-void write(String str)写入字符。
-void write(string str,int off,int Len)写入字符串的某一部分,off字符串的开始索引,Len写的字符个数。
-void flush()新该流的缓冲。
-void close()关闭此流,但要先刷新它。
构造方法:
OutputStreamWriter(OutputStream out)创建使用字符编码的OutputStreamWriter
OutputStreamWriter(OutputStream out,String charsetName)创建使用指定字符集的 OutputStreamWriter
参数:
OutputStream out:字节输出流,可以用来写转换之后的字节到文件中
String charsetName:指定的编码表名称,不区分大小写,可以是utf-8/UTF-8,gbk/GBK,..不指定默认使用UTF-8
使用步骤:
1.创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称
2.使用OutputStreamWriter对象中的方法write,把字符转换为字节存储缓冲区中(编码)
3.使用OutputStreamwriter对象中的方法flush,把内存缓冲区中的字节刷新到文件中(使用字节流写字节的过程)
4.释放资源
*/
public class Demo02 {
public static void main(String[] args) throws IOException {
write_utf_8();
write_gbk();
}
private static void write_gbk() throws IOException {
// 1.创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("C:\\t430\\java\\anything1\\gbk.txt"),"gbk");
//2.使用OutputStreamWriter对象中的方法write,把字符转换为字节存储缓冲区中(编码)
osw.write("你好");
osw.flush();
osw.close();
}
/*
使用转换流OutputStreamWriter写UTF-8格式的文件
*/
private static void write_utf_8() throws IOException {
// 1.创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称
//OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("C:\\t430\\java\\anything1\\utf_8.txt"),"utf-8");
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("C:\\t430\\java\\anything1\\utf_8.txt"));//不指定也是默认utf-8
//2.使用OutputStreamWriter对象中的方法write,把字符转换为字节存储缓冲区中(编码)
osw.write("你好");
osw.flush();
osw.close();
}
}
InputStreamReader
package file.转换流;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
/*
java.io.InputStreamReader extends Reader
InputStreamReader:是字节流通向字符流的桥梁:它使用指定的charset 读取字节并将其解码为字符。(解码:把看不懂的变成能看懂的)
继承自父类的共性成员方法:
int read()读取单个字符并返回。
int read(char[]cbuf)一次读取多个字符,将字符读入数组。
void close()关闭该流并释放与之关联的所有资源。
构造方法:
InputStreamReader(InputStream in)创建一个使用默认字符集的InputStreamReader
InputStreamReader(InputStream in,String charsetName)创建使用指定字符集 InputStreamReader
参数:
InputStream in:字节输入流,用来读取文件中保存的字节
String charsetName:指定的编码表名称,不区分大小写,可以是utf-8/UTF-8,gbk/GBK,...不指定默认使用UTF-8
使用步骤:
1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称
2.使用InputStreamReader对象中的方法read读取文件
3.释放资源
注意事项:构造方法中指定的编码表名称要和文件的编码相同,否则会发生乱码
*/
public class Demo03 {
public static void main(String[] args) throws IOException {
read_utf_8();
read_gbk();
}
private static void read_gbk() throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("C:\\t430\\java\\anything1\\gbk.txt"),"gbk");
int len =0;
while ((len = isr.read())!=-1){
System.out.println((char)len);
}
isr.close();
}
/*
使用InputStreamReader读取UTF-8格式的文件
*/
private static void read_utf_8() throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("C:\\t430\\java\\anything1\\utf_8.txt"),"utf-8");//不知名就是默认u8
int len =0;
while ((len = isr.read())!=-1){
System.out.println((char)len);
}
isr.close();
}
}
联系:转换文件编码
package file.转换流;
import java.io.*;
/*
练习:转换文件编码
将GBK编码的文本文件,转换为UTF-8编码的文本文件。
分析:
1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称GBK
2.创建OutputStreamlwriter对象,构造方法中传递字节输出流和指定的编码表名称UTF-8
3.使用InputStreamReader对象中的方法read读取文件
4.使用OutputStreamwriter对象中的方法write,把读取的数据写入到文件中
5.释放资源
*/
public class Demo04 {
public static void main(String[] args) throws IOException {
//1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称GBK
InputStreamReader isr = new InputStreamReader(new FileInputStream("C:\\t430\\java\\anything1\\我是GBK格式的文本.txt"),"gbk");
//2.创建OutputStreamlwriter对象,构造方法中传递字节输出流和指定的编码表名称UTF-8
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("C:\\t430\\java\\anything1\\我是UTF_8格式的文本.txt"),"UTF-8");
//3.使用InputStreamReader对象中的方法read读取文件
int len = 0;
while ((len = isr.read())!=-1){
//4.使用OutputStreamwriter对象中的方法write,把读取的数据写入到文件中
osw.write(len);
}
osw.close();
isr.close();
}
}
09 序列化流
序列化与反序列化

对象的序列化流ObjectOutputStream
package file.序列化流;
import java.io.Serializable;
/*
序列化和反序列化的时候,会抛出NotSerializableException没有序列化异常
类通过实现java.io.Serializable接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。
Serializable接口也叫标记型接口
要进行序列化和反序列化的类必须实现Serializable接口,就会给类添加一个标记
当我们进行序列化和反序列化的时候,就会检测类上是否有这个标记
有:就可以序列化和反序列化
没有:就会抛出NotSerializableException异常
去市场买肉-->肉上有一个蓝色章(检测合格)-->放心购买-->买回来怎么吃随意
*/
public class Person implements Serializable { //没有这个接口就会异常
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package file.序列化流;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
/*
java.io.ObjectOutputStream extends OutputStream
ObjectOutputStream:对象的序列化流
作用:把对象以流的方式写入到文件中保存
构造方法:
ObjectOutputStream(OutputStream out)创建SA指定 OutputStreamObjectOutputStream
参数:OutputStream out:字节输出流
特有的成员方法:
void writeObject(Object obj)指定的对象写A ObjectOutputStream
使用步骤:
1.创建ObjectOutputStream对象,构造方法中传递字节输出流
2.使用ObjectOutputStream对象中的方法writeObject,把对象写入到文件中
3.释放资源
*/
public class Demo01 {
public static void main(String[] args) throws IOException {
//1.创建ObjectOutputStream对象,构造方法中传递字节输出流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\t430\\java\\anything1\\person.txt"));
//2.使用ObjectOutputStream对象中的方法writeObject,把对象写入到文件中
oos.writeObject(new Person("小美女",18));
oos.close();
}
}
对象的反序列化流ObjectInputStream
package file.序列化流;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
/*
java.io.ObjectInputStream extends InputStream
ObjectInputStream:对象的反序列化流
作用:把文件中保存的对象,以流的方式读取出来使用
构造方法:
ObjectInputStream(InputStream in)创建A定 InputStream 取 ObjectInputStreamo
参数:InputStream in:字节输入流
特有的成员方法:Object readObject()A ObjectInputStream 读取对象。
使用步骤:
1.创建ObjectInputStream对象,构造方法中传递字节输入流
2.使用ObjectInputStream对象中的方法readObject读取保存对象的文件
3.释放资源
4.使用读取出来的对象(打印)
readObject方法声明抛出了ClassNotFoundException(class文件找不到异常)
当不存在对象的class文件时抛出此异常
反序列化的前提:
1.类必须实现Serializable
2.必须存在类对应的class文件
*/
public class Demo02 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// 1.创建ObjectInputStream对象,构造方法中传递字节输入流
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\t430\\java\\anything1\\person.txt"));
//2.使用ObjectInputStream对象中的方法readObject读取保存对象的文件
Object o = ois.readObject();
ois.close();
System.out.println(o);
Person o1 = (Person) o;
System.out.println(o1.getName()+o1.getAge());
}
}
transient关键字——瞬态关键字
InvalidClassException异常_原理
练习:序列化集合
package file.序列化流;
import java.io.*;
import java.util.ArrayList;
/*
练习:序列化集合
当我们想在文件中保存多个对象的时候
可以把多个对象存储到一个集合中
分析:对集合进序列化和反序列化
1.定义一个存储Person对象的Arraylist集合
2.往ArrayList集合中存储Person对象
3.创建一个序列化流ObjectOutputStream对象
4.使用ObjectoutputStream对象中的方法writeobject,对集合进行序列化
5,创建一个反序列化ObjectInputStream对象
6.使用ObjectInputStream对象中的方法readobject读取文件中保存的集合
7.把object类型的集合转换为ArrayList类型
8.遍历ArrayList集合
9.释放资源
*/
public class Demo03 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//1.定义一个存储Person对象的Arraylist集合
ArrayList<Person> list = new ArrayList<>();
//2.往ArrayList集合中存储Person对象
list.add(new Person("张三",18));
list.add(new Person("李四",19));
list.add(new Person("王五",20));
// 3.创建一个序列化流ObjectOutputStream对象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\t430\\java\\anything1\\list.txt"));
// 4.使用ObjectoutputStream对象中的方法writeobject,对集合进行序列化
oos.writeObject(list);
// 5,创建一个反序列化ObjectInputStream对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\t430\\java\\anything1\\list.txt"));
// 6.使用ObjectInputStream对象中的方法readobject读取文件中保存的集合
Object o = ois.readObject();
// 7.把object类型的集合转换为ArrayList类型
ArrayList<Person> list2 = (ArrayList<Person>)o;
// 8.遍历ArrayList集合
for (Person p:list2){
System.out.println(p);
}
// 9.释放资源
ois.close();
oos.close();
}
}
10 打印流
package file.打印流;
import java.io.FileNotFoundException;
import java.io.PrintStream;
/*
java.io.PrintStream:打印流
PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。
PrintStream特点:
1.只负责数据的输出,不负责数据的读取
2.与其他输出流不同,PrintStream永远不会抛出IOException
3.有特有的方法,print,println
void print(任意类型的值)
void println(任意类型的值并换行)
构造方法:
PrintStream(File file):输出的目的地是一个文件
PrintStream(OutputStream out):输出的目的地是一个字节输出流
PrintStream(String fileName):输出的目的地是一个文件路径
PrintStream extends OutputStream
继承自父类的成员方法:
public void close():关闭此输出流并释放与此流相关联的任何系统资源。
public void flush():刷新此输出流并强制任何缓冲的输出字节被写出。
public void write(byte[]b):将 b.length字节从指定的字节数组写入此输出流。
public void write(byte[]b,int off,int Len):从指定的字节数组写入Len字节,从偏移量 off开始输出到此输出流。
public abstract void write(int b):将指定的字节输出流。
注意:
如果使用继承自父类的write方法写数据,那么查看数据的时候会查询编码表97->a
如果使用自己特有的方法print/println方法写数据,写的数据原样输出97->97
*/
public class Demo01 {
public static void main(String[] args) throws FileNotFoundException {
//System.out.println("hello world");
//创建打印流PrintStream对象,构造方法中绑定要输出的目的地
PrintStream ps = new PrintStream("C:\\t430\\java\\anything1\\print.txt");
//如果使用继承自父类的write方法写数据,那么查看数据的时候会查询编码表97->a
ps.write(97);
//如果使用自己特有的方法print/println方法写数据,写的数据原样输出97->97
ps.println(97);
ps.println(8.8);
ps.println('a');
ps.println("hello world");
ps.println(true);
ps.close();
}
}
打印流可以改变语句的目的地(打印流的流向)
package file.打印流;
import java.io.FileNotFoundException;
import java.io.PrintStream;
/*
可以改变输出语句的目的地(打印流的流向)
输出语句,默认在控制台输出
使用System.setOut方法改变输出语句的目的地改为参数中传递的打印流的目的地
static void setOut(PrintStream out)
重新分配"标准"输出流。
*/
public class Demo02 {
public static void main(String[] args) throws FileNotFoundException {
System.out.println("我是在控制台输出");
PrintStream ps = new PrintStream("C:\\t430\\java\\anything1\\目的地是打印流.txt");
System.setOut(ps);//把输出流的目的地改编为打印流的目的地
System.out.println("我在打印流的目的地输出");
ps.close();
}
}


浙公网安备 33010602011771号