Java学习笔记(三) IO流

I/O 框架

流的概念

概念:内存与存储设备之间传输数据的通道

数据借助流传输

流的分类

  • 按方向【重点】

    • 输入流:将<存储设备>中的内容读入到<内存>中
    • 输出流:将<内存>中的内容写入到<存储设备>中
  • 按单位

    • 字节流:以字节为单位,可以读写所有数据
    • 字符流:以字符为单位,只能读写文本数据
  • 按功能

    • 节点流:具有实际传输数据的读写功能
    • 过滤流:在节点流的基础之上增强功能

字节流

  • 字节流的父类(抽象类)
    • InputStream: 字节输入流
    • OutputStream: 字节输出流

文件字节流

  • FileInputStream:

    • public int read(byte[] b)//从流中读取多个字节,将读到内容存入b数组,返回实际读到的字节数;如果达到文件的尾部,则返回-1
  • FileOutputStream

    • public void write(byte[] b)//一次写入多个字节,将b数组中所有字节,写入输出流
/*
FileInputStream 的使用
*/

//文件不一定存在,会有异常  先创建文件内容为abcdefg
public static void main(String[] args) throws Exception{
    //创建对象,指定路径
    FileInputStream fis=new FileInputStream("d:\\aaa.txt");
    //单个字节读取
    int data=0;
    while((date=fis.read())!=-1){
        System.out.print((char)data);
    }
    //关闭文件
    fis.close();
    
    //多个字节读取
    byte[] buf = new byte[3];
   // int count=fis.read(buf); //返回值是读取的个数
    int count=0;
    while((count=fis.read(buf))!=-1){
        System.out.println(new String(buf,0,count));
    }
    
}
/*
FileOutputStream
*/

public static void main(String[] args) throws Exception{
    //创建文件字节输出流对象
    FileOutputStream fos = new FileOutputStream("d\\bbb.txt");
    //传入参数 除了文件路径外 还有true 不会覆盖文件
    //写入文件
    fos.write(97); //a
    fos.write('b');
    
    //会覆盖 ab
    String str= "helloworld";
    fos.write(str.getBytes());
    //关闭
    fos.close();
}

字节缓存流

  • 缓存流:BufferedInputStream/BufferedOutputStream
    • 提高IO效率,减少访问磁盘的次数
    • 数据存储在缓冲区中,flush是将缓冲区的内容写入文件中,也可以直接close.
/*
使用字节缓冲流读取
*/

public static void main(String[] args) throw Exception{
    //创建BufferedInputStream
    FileInputStream fis=new FileInputStream("d:\\aaa.txt");
    BufferedInputStream bis=new BufferedInputStream(fis);
    
    //读取
    int data=0;
    while((data=bis.read())!=-1){
		System.out.print((char)data);
    }
    //关闭 
    bis.close();//默认会把文件字节流也关闭
}
//也可以自己创建缓冲区

/*
字节缓冲流写入文件
*/
public static void main(String[] args) throws Exception{
    //创建字节输出
    FileOutputStream fos=new FileOutputStream("d:\\buffer.txt");
    BufferedOutputStream bos=new BufferedOutputStream(fos);
    
    //写入文件
    for(int i=0;i<10;i++){
		bos.write("helloworld\n".getBytes());//写入8k缓冲区
        bos.flush();//刷新到硬盘
    }
    //关闭
    bos.close();//内部调用flush方法
}

对象流

  • ObjectOutputStream/ObjectInputStream
    • 增强了缓冲区功能
    • 增强了读写8种基本数据类型和字符串功能
    • 增强了读写对象的功能

使用流传输对象的过程称为序列化、反序列化

创建好Student类 属性 为name ,age

必须要实现 接口Serializable使用接口就行

序列化(写入对象)

/*
ObjectOutputStream
要求序列化的类必须实现 接口Serializable
*/
public static void main(String[] args) throws Exception{
    //创建对象
    FileOutputStream fos=new FileOutputStream("d:\\stu.bin");
    ObjectOutputStream oos=new ObjectOutputStream(fos);
    
    //序列化
    Student zhangsan=new Student("张三",23);
    oos.writeObject(zhangsan);
    
    //关闭
    oos.close();
    

}

反序列化(读取对象)

/*
ObjectInputStream


*/
public static void main(String[] args) throws Exception{
	//创建流
    FileInputStream fis=new FileInputStream("b:\\stu.bin");
    ObjectInputStream ois=new ObjectInputStream(fis);
    
    //读取文件。反序列化
    Student s= (Student)ois.readObject();
    //只有一个对象读多个会异常
    System.out.println(s.toString());
    ois.close()
}

注意事项
1)序列化类必须事项Serializable接口
2)序列化类中对象属性要求实现Serializable接口
3)序列化版本号ID,保证序列化的类和反序列化的类是同一个类
4)使用transient(瞬间的)修饰属性,这个属性不能序列化了
5)静态属性也不能序列化
6)序列化多个对象,可以把对象放到集合里面。序列化集合就可以

编码方式

  • ISO-8859-1 收录除了ASCII外,西欧、希腊、泰国、阿拉伯、希伯来对应的文字符号
  • UTF-8 针对Unicode码表的可变长度字符编码
  • GB2312 简体中文
  • GBK 简体中文、扩充
  • BIG5 台湾,繁体

当编码方式和解码方式不一样 就会出现乱码

字符流

字节流读取中文 会出现乱码

  • 字符流的父类(抽象类)
    • Reader:字符输入流
    • Writer:字符输出流

文件字符流

  • FileReader:
    • public int read(char[] c)//从流中读取多个字符,将读到内容存入c数组,返回实际读到的字符数;如果读到文件的尾部,则返回-1
  • FileWriter
    • public void write(String str);//一次写入多个字符,将b数组中所有字符,写入输出流

不能复制 图片,声音等二进制编码的文件

字节流可以复制任意文件

/*
FileReader
*/
public static void main(String[] args) throws Exception{
    //创建
    FileReader fr=new FileReader("d:\\hello.txt");
    
    //读取
    //单个字符读取
    int data=0;
    while((data=fr.read())!=-1){ //读取一个字符
        System.out.print((char)data);
        
    }
    //用缓冲区
    char[] buf=new char[1024];
    int count=0;
    while((count=fr.read(buf))!=-1){
        System.out.println(new String(buf,0,count));
    }
    //关闭
    fr.close();
}
/*
FileWriter
*/
public static void main(String[] args)throws Exception{
    //创建对象
    FileWriter fw=new FileWriter("d:\\write.txt");
    
    //写入
    for(int i=0;i<5;i++){
        fw.write("我真棒!\r\n");
        fw.flush();
    }
    //关闭
    fw.close();
}

字符缓存流

  • BufferedReader/BufferedWriter
    • 高效读写
    • 支持输入换行符
    • 可以一次写一行、读一行
/*
BufferedReader
*/
public static void main(String[] args)throws Exception{
    //创建对象
    FileReader fr=new FileReader("d:\\write.txt");
    BufferedReader br=new BufferedReader(fr);
    
    //读取
    char[] buf=new char[1024];
    int count=0;
    while((count=br.read(buf))!=-1){
		System.out.print(new String(buf,0,count));
    }
    //一行一行读
   String line=null;
    while((line= br.readLine())!=-1){
        System.out.println(line);
    }
   
    //关闭
    br.close();
}
/*
BufferedWriter
*/
public static void main(String[] args)throws Exception{
    //创建对象
    FileWriter fw=new FileWriter("d:\\buffer.txt");
    BufferedWriter bw=new BufferedWriter(fw);
    
    //写入
    for(int i=0;i<5;i++){
        bw.write("我真厉害");
        bw.newLine();//写入一个换行符
        bw.flush();
    }
    
    //关闭
    bw.close();
    
    
}

打印流

  • PrintWriter:
    • 封装了 print()/println()方法,支持吸入后换行
    • 支持数据原样打印
/*
PrintWriter
*/

public static void main(String[] args) throws Exception{
	PrintWriter pw =new PrintWriter("d:\\print.txt");
    //打印数据
    pw.println(97);
    pw.println(true);
    pw.println(3.14);
    pw.println('a');
    
    //关闭
    pw.close();
    
}

转换流

  • 桥转换流:InputStreamReader / OutputStreamWriter
    • 可将字节流转换为字符流
    • 可设置字符的编码方式
//InputStreamReader读取文件,指定编码
FileInputStream fis=new FileInputStream("d:\\write.txt");
InputStreamReader isr=new InputStreamReader(fis,"utf-8");
//读取文件
int data=0;
while((data=isr.read())!=-1){
	System.out.print((char)data);
}
//关闭
isr.close();

//OutputStreamWriter 写入文件 使用指定编码

FileOutputStream fos=new FileOutputStream("d:\\info.txt");
OutputStreamWriter osw=new OutputStreamWriter(fos,"gbk");

//写入
for(int i=0;i<10;i++){
    osw.write("我是最胖的\r\n");
    osw.flush();
}
//关闭
osw.close();

File类

  • 代表物理盘符中的一个文件或者文件夹
/*
File 类的使用
分隔符
文件操作
文件夹操作
*/
public static void main(String[] args){
    separator();
    fileOpe();
}

public static void separator(){
    System.out.println("路径分隔符"+File.pathSeparator);//;
    System.out.println("名称分隔符"+File.separator);// /
}

//文件操作
public static void fileOpe() throws Exception{
    //创建文件
    File file=new File("d:\\file.txt");
    //判断文件是否已经存在,不存在就创建
    if(!file.exists()){
		boolean b=file.createNewFile();
    }
    
    
    //删除文件
    //1.直接删除
    boolean f=file.delete();
    //2.使用jvm退出时删除
    file.deleteOnExit();
    
    //获取文件信息
    //绝对路径
    file.getAbsolutePath();
    //获取路径
    file.getPath();
    //获取文件名称
    file.getName();
    //获取父目录
    file.getParent();
    //获取文件长度
    file.length();
    //创建时间
    new Date(file.lastModified().toLocaleString());
    
    //判断
    //是否可写
    file.canWrite();
    //是不是分件
    file.isFile();
    //是否隐藏
    file.isHidden();
    
}


//文件夹操作

public static void directoryOpe() throws Exception{
    //创建
    
    File dir=new File("d:\\aaa\\bbb\\ccc");
    if(!dir.exisits()){
        //dir.mkdir();//只能创建单级目录
        dir.mkdirs();//创建多级目录
    }
    //删除文件夹
    //直接删除  只删除 最底层ccc ,而且必须是空目录
    dir.delete();
    
    //使用jvm删除
    dir.deleteOnExit();
    
    //获取文件夹信息
    //绝对路径
    dir.getAbsolutePath();
    //路径
    dir.getPath();
    //文件夹名称 最底层
    dir.getName();
    //父目录
    dir.getParent();
    //创建时间
    new Date(dir.lastModified()).toLocaleString();
    
    //判断
    //是否是文件夹
    dir.isDirectory();
    //是否隐藏
    dir.isHidden();
    
    
    //遍历文件夹
    File dir2=new File("d:\\图片");
    String[] files=dir2.list(); 
    for(String s : files){
		System.out.println(s);
    }
    
}

FileFilter 接口

  • public interface FIleFilter
    • boolean accept(File pathname)
  • 当调用File类中的listFiles()方法时,支持传入File Filter接口实现类,对获取文件进行过滤,只有满足条件的文件才能出现在listFiles()的返回值中
  File dir2=new File("d:\\图片");
    File[] files=dir2.listFiles(new FileFilter(){
        
        public boolean accept(File pathname){
            //只有 jpg格式的文件
            if(pathname.getName().endsWith(.jpg)){
				return true;
            }
            return false;
        }
    }); 
    for(File s : files){
		System.out.println(s);
    }
//递归遍历文件夹
public static void main(String[] args){
	listDir(new File("d:\\myfiles"));
}
public static void listDir(File dir){
    File[] files=dir.listFiles();
    System.out.println(file.getAbsolutePath())
    if(files!= null && files.length>0){
        for(File file : files){
            if(file.isDirectory()){
                listDir(file);
            }else{
				System.out.println(file.getAbsolutePath());
            }
        }
    }
}

//递归删除目录
public static void deleteDir(File dir){
    File[] files=dir.listFiles();
   
    if(files!= null && files.length>0){
        for(File file : files){
            if(file.isDirectory()){
                deleteDir(file);
            }else{
				files.delete();
            }
        }
      
    }
    dir.delete();
}

补充:Properties

属性集合

特点:

  • 存储属性名和属性值
  • 属性名和属性值都是字符串类型
  • 没有泛型
  • 和流有关
//创建
Properties ps=new Properties();

//添加数据
ps.setPeoperty("username","zhangsan");
ps.setPeoperty("age","20");

//遍历
//1 keySet


//2 entrySet

//3 stringPropertyNames()
Set<String> prs=ps.stringPropertyNames();
for(String pro : prs){
    System.out.println(pro+prs.getProperty(pro));
}

//和流有关的方法
PrintWriter pw =new PrintWriter("d:\\print.txt");
prs.list(pw);
pw.close();

//保存
FileOutputStream fos=new FileOutputStream("d:\\store.properties");
prs.store(fos,"zhushi");
fos.close();

//load方法 加载
Properties prs2=new Properties();
FileInputStream fis=new FileInputStream("d:\\store.properties");
prs2.load(fis);
fis.close();
System.out.println(prs2.toString());

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值