Java笔记--08

IO需要掌握的16个流
FileInputStream
FileOutputStream
FileReader
FileWriter

BufferedReader
BufferedWriter
BufferedInputStream
BufferedOutputStream

DataInputStream
DataOutputStream

ObjectInputStream
ObjectOutputStream

转换流(字节流转换成字符流)
InputStreamReader
OutputStreamWriter

PrintWriter
PrintStream(标准的输出流:默认输出到控制台)


FileInputStream

java.io.InputStream;
     java.io.FileInputStream;文件字节数入流,按照字节方式读取文件
     1.要读取某文件,先给这个文件创建一个"输入流"
     //文件路径
    String filePath = "txt";//相对路径,相对当前而言,在当前路径找下去;也可以是绝对路径,F:\\workspace\\08\\txt或者F:/workspace/08/txt
    FileInputStream fis = new FileInputStream(filePath);
    2.开始读(如果已经读取到文件的末尾,就会返回-1)
    int temp=0;
    while((temp=fis.read()) != -1){
    System.out.println(temp);
    }
    3.释放资源,为了保证流一定会释放,所以在finally语句块中执行
    finally{
    fis.close();
    }

注意:在读取文件时可能出现FileNotFountException,而该异常是编译期异常,因此要进行try…catch…处理
用上面这样的程序存在缺点:频繁访问磁盘,伤害磁盘,并且效率低,因此系统提供了int read(byte [] bytes);方法
该方法在读取之前在内存中准备一个byte数组,每次读取多个字节存储到bytes数组中一次读取多个字节,不是单个字节读取了,效率高

1.创建输入流
FileInputStream fis = new FileInputStream("txt");//txt.txt文件中存储的是abcd
2.开始读
//准备一个数组并声明一次最多可以读取几个字节
byte [] bytes = new byte[3];每一次最多读取3个字节
int i1 = fis.read(bytes);//3
//注意:int read(byte [] bytes);该方法返回的int类型的值代表的是:这次读取了多少个字节
//将byte数组转换成字符串
System.out.println(new String(bytes));//abc
int i2 = fis.read(bytes);//1
System.out.println(new String(bytes));//dbc
如果要想正确显示最后一次读取的数据,应该用String(byte [] bytes,int offset,int length);方法;其中offset是从几开始读,length是读取的长度
System.out.println(new String(bytes,0,i2));//dbc
3.关闭流资源
fis.close();
用数组的方式循环读取
FileInputStream fis = new FileInputStream("Test");
byte [] bytes = new byte[1024];//每次读取1KB
int temp = 0;
while((temp=fis.read(bytes)) != -1){
//将byte数组有效的数据转换成字符串
      System.out.print(new String(bytes,0,temp));
       }
fis.close();
注意:因为Test文件中本身自带换行,因此在输出时不能再用println()方法了,而要用print()方法
int available();返回流中剩余的估计字节数
skip(long n);从输入流中跳过并丢弃n个字节的数据

FileOutputStream

java.io.OutputStream;
    java.io.FileOutputStream;文件字节输出流,将计算机内存中的数据写入硬盘文件中
FileOutputStream fos = null;
    try{
    //1.创建文件字节输出流
    //fos = new FileOutputStream("temp01");//谨慎使用,会将源文件覆盖
    //以追加的方式写入
    fos = new FileOutputStream("temp01",true);
    //2.开始写
    String msg = "HelloWorld!";
    //将String转换成byte数组
    byte[] bytes = msg.getBytes();
    fos.write(bytes);
    //write(byte [] bytes,int offset, int length);该方法可以将数组中指定长度写入
   //推荐最后的时候为了保证数据完全写入硬盘,所以要刷新
   fos.flush();
    }catch(Exception e){
    e.printStream();
    }finally{
    //3.关闭流资源
    if(fos != null){
    try{
        fos.close();
       }catch(Exception e){
        e.printStream();
    }
    }
}

关于文件复制粘贴
以下为了书写的简便不采用try…catch…进行处理,而是用throws语句进行声明,正常编程中要用try…catch…处理

//创建输入流
FileInputStream fis = new FileInputStream("FileOutputStream.java");
//创建输出流
FileOutputStream fos = new FileOutputStream("F:/FileOutputStream.java");
//一边读一边写
byte [] bytes = new byte[1024];
int temp = 0;
while(temp=fis.read(bytes) != -1){
//将byte数组中的内容直接写入
     fos.write(bytes,0,temp);
}
//刷新
fos.flush();
//关闭流资源
fis.close();
fos.close();

FileReader

java.io.Reader;
     java.io.InputStreamReader;//转换流(字节输入流-->字符输入流)
      java.io.FileReader;文件字符输入流
//创建字符输入流
FileReader fr = null;
fr = new FileReader("Test");
//开始读
char [] chars = new char[512];//1KB,一个字符占两个字节
int temp = 0;
while((temp=fr.read(chars))!=-1){
//将char数组有效部分转换成字符串
    System.out.print(new String(chars,0,temp));
    }
//关闭
fr.close();

FileWriter

java.io.Writer;
    java.io.OutputStreamWriter;//转换流(字节输出流-->字符输出流)
     java.io.FileWriter;文件字符输出流
//创建字符输出流
//FileWriter fw = new FileWriter("temp02");//覆盖
FileWriter fw = new FileWriter("temp02",true);//追加
//开始写
fw.write("海波东--冰皇");
//将char数组的一部分写入
char [] chars = {'我','看','过','好','多','小','说','了','!'};
fw.write(chars,0,3);//我看过
//刷新
fw.flush();
fw.close();

用FileReader和FileWriter实现文件复制
只能复制纯文本

FileReader fr = new FileReader("Test02.java");
FileWriter fw = new FileWriter("F:/Test02.java");

char [] chars = new char[512];//1KB
int temp = 0;
while((temp=fr.read(chars))!=-1){
    //写
    fw.write(chars,0,temp);
    }
fw.flush();
fr.close();
fw.close();

BufferedReader;带有缓冲区的字符输入流
BufferedWriter;带有缓冲区的字符输出流
BufferedInputStream;带有缓冲区的字节输入流
BufferedOutputStream;带有缓冲区的字节输出流

java.io.Reader;
    java.io.BufferedReader;

//创建一个带有缓冲区的字符输入流
FileReader fr = new FileReader("BufferedReaderTest.java");//创建一个文件字符输入流
BufferedReader br = new BufferedReader(fr);//将文件字符输入流包装成带有缓冲区的字符输入流
//根据流出现的位置,流又可以分为:包装流和节点流,FileReader fr是一个节点流,BufferedReader br是一个包装流
//上面两句可以合为一句
BufferedReader br = new BufferedReader(new FileReader("BufferedReaderTest.java"));
//开始读
String temp = null;
while((temp=br.readLine())!=null){//br.readLine()方法读取一行,但是行尾不带换行符
    System.out.println(temp);
    }
//关闭流资源
//注意:关闭的时候只需要关闭最外层的包装流(这里有一个装饰者模式)
br.close();

如何将FileInputStream包装成BufferedReader?

//创建一个文件字符输入流
FileInputStream fis = new FileInputStream("BufferedReaderTest.java");
//转换流(将字节流转换成字符流)
InputStreamReader isr = new InputStreamReader(fis);//isr是字符流
//将字符流包装成带有缓冲区的字符流
BufferedReader br = new BufferedReader(isr);
//可以将上面的三句话合成一句
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("BufferedReaderTest.java")));
后面的代码和上面的一样,此处省略

接收用户键盘输入
以前的方式:采用Scanner 类;

Scanner s = new Scanner(System.in);//System.in是一个标准的输入流,默认接收键盘的输入
//程序执行到此处停下来,等待用户的输入
String str =s.next();

注意:该方式默认以空格作为分割,因此不能从键盘接收hello world!只能接收到hello
使用BufferedReader用来接收用户的输入

BufferedReader br = new BufferedReader(InputStreamReader(System.in));
//接受输入(每一次接收一行)
String str = br.readLine();

BufferedWriter

java.io.Writer;
    java.io.BufferedWriter;

//创建带有缓冲区的字符输出流
BufferedWriter bw = new BufferedWriter(new FileWriter("temp03"));
//开始写
bw.write("我现在不怎么看小说了,");
//写入一个行分隔符
bw.newLine();
bw.write("时间反而多了!");
//刷新
bw.flush();
//关闭
bw.close();

使用BufferedReader和BufferedWriter完成复制

//创建带有缓冲的字符输入流
BufferedReader br = new BufferedReader(new FileReader("Copy.java"));
//创建带有缓冲区的字符输出流
BufferedWriter bw = new BufferedWriter(new FileWriter(F:/Copy.java));
//边读边写
String temp = null;
while((temp=br.readLine())!=null){
    bw.write(temp);
    bw.readLine();//添加一个换行符,拷贝出来的文件会比源文件大2字节,一个换行符占2字节
    }
//刷新
bw.flush();
//关闭
br.close();
bw.close();

DataOutputStream;数据字节输出流
可以将内存中的”int i=10;”写入到硬盘文件中,写进去的不是字符串,写进去的是二进制数据,带类型

java.io.OutputStream;
    java.io.FileterOutputStream;
        java.io.DataOutputStream;

//创建数据字节输出流
DataOutputStream dos = new DataOutputStream(new FileOutputStream("temp04"));
//准备数据
byte b = 10;
short s = 11;
int i = 12;
long l = 1000L;
float f = 3.2f;
double d = 3.2;
boolean flag = true;
char c = 'a';
//写
dos.writeByte(b);
dos.writeShort(s);
dos.writeInt(i);
dos.writeLong(l);
dos.writeFloat(f);
dos.writeDouble(d);
dos.writeBoolean(flag);
dos.writeChar(c);
//刷新dos.flush();
//关闭
dos.close();

注意:使用DataOutputStream写入的数据,只能用DataInputStream读取

DataInputStream

java.io.InputStream;
    java.io.FilterInputStream;
        java.io.DataInputStream;

//创建输入流
DataInputStream dis = new DataInputStream(new FileInputStream("temp04"));
//读
//注意:要使用该流读取数据,必须提前知道该文件中数据的存储格式、顺序且读的顺序必须和写入的顺序相同
byte b = dis.readByte();
short s = dis.readShort();
int i = dis.readInt();
long l = dis.readLong();
float f = dis.readFloat();
double d = dis.readDouble();
boolean flag = dis.readBoolean();
char c = dis.readChar();
//下面接输出语句,不一一写了
System.out.print(b);
dis.close();

PrintStream;标准的输出流,默认打印到控制台,以字节方式
PrintWriter;以字符方式
PrintStream;

java.io.OutputStream;
    java.io.FilterOutputStream;
        java.io.PrintStream;

 //默认是输出到控制台的
System.out.println("HelloWorld!");
//还可以写成下面这种形式
PrintStream ps = System.out;
ps.println("HelloWorle!");
//可以改变输出方向
System.setOut(new PrintStream(new FileOutputStream("log")));
//再次输出则打印到log,通常使用这种方式记录日志
System.out.println("hiahiahia...");

ObjectOutputStream;序列化JAVA对象到硬盘(Serial)
ObjectInputStream将硬盘中的数据”反序列化”到JVM内存中(DeSerial)
序列化

java.io.OutputStream;
    java.io.ObjectOutputStream;
//创建java对象
User u = new User("张三","男","21");
//创建输出流(序列化流)(JVM中的java对象状态保存到硬盘中)
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("temp05"));
//写
oos.writeObject(u);
//刷新
oos.flush();
//关闭
oos.close();

注意:User对象要想序列化,必须实现Serializable接口,而Serializable接口中有没有方法,像这样的接口,我们称为标识接口,标识接口的作用:起到标识作用,JVM如果看到该标识,会对它特殊待遇
反序列化

java.io.InputStream;
    java.io.ObjectOnputStream;
//创建反序列化流
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("temp05"));
//反序列化
Object o = ois.readObject();
//输出到控制台
System.out.println(o);//会调用User里重写的toString方法,结果为:[User:姓名:张三,性别:男,年龄:21]
//关闭
ois.close();

关于序列化版本号和transient关键字
因为User实现了Serializable接口,JVM会特殊待遇:会给该类添加一个属性
static final long serialVersionUID = 124941495L;
每次该类改动之后再次编译,系统都会给该类一个serialVersionUID,如果让系统自动生成,就会出现以前序列化的对象在反序列化的时候会报异常,那是因为系统每次为该类添加属性并赋值是不同的,因此在实际编程中,通常都是我们自己在需要序列化的类中写一个序列化版本号,另外,如果不想让该类中的某属性序列化,则在该属性的前面用关键字transient关键字修饰
java.io.File;
1.File类和流无关,不能通过该类完成文件的读写
2.File是文件和目录路径名的抽象表示形式
File代表的是硬盘上的Directory和file

File f1 = new File("Test01.java");//代表的是文件
File f2 = new File(D:/A/B/C);//代表的是目录
File f3 = new File(D:/TT);
System.out.println(f1.exists());//判断该文件是否存在
//如果不存在,创建该目录或文件
if(!f3.exists()){
f2.mkdir();//创建目录
f2.createNewFile();//创建文件
}
if(!f2.exists()){
f2.mkdirs();//创建多重目录
}

File中常用的方法

   String getAbsolutePath();获取绝对路径
    String getName();获取文件名
    String getParent();获取父路径
    boolean isDirectory();判断该文件是否是目录
    boolean isFile();判断该文件是否是文件
    long lastModified();获取文件最后一次修改的时间
    long length();获取文件的长度(字节数)
    File [] listFiles();//列出子文件并保存在数组里

如果要遍历数组里所有的以.java结尾的子文件,可以用增强for循环加判断条件

File f = new File(D:/workspace);
File [] fs = f.listFiles();
for(File f:fs){
    if(f.getAbsolutePath().endsWith(.java)){
            System.out.println(f.getAbsolutePath());
        }
    }

使用递归,找出某目录下的所有子目录以及子文件

import java.io.*;
public class Test{
    public static void main(String [] args){
        File f = new File("F:/workspace")
        //调用方法完成查找
        method(f);
        }
    public static void method(File f){
        if(f.isFile()){
        return;
        }
    File [] fs = f.listFiles();
    for(File subF:fs){
            System.out.println(subF.getAbsolutePath());
            method(subF);
            }
        }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值