java基础之 IO流

输入:从文件中读取、从数据库读取、网络上下载
输出:写到文件中、存入数据库、上传到网络

IO流的使用步骤
1.创建节点流
2.封装过滤流
3.读/写 数据
4.关闭流(只关最外层的)

java.io.File   
一个File对象代表磁盘上的一个文件或目录;

File file = new File("1.txt");//表示创建一个文件名为1的txt文件对象
File file2 = new File("F:\\","2.txt");//目录名,文件名
File dir = new File("F:\\");   //先创建一个目录对象
File file3 = new File(dir,"3.txt");//用File对象做目录创建文件
File file4 = new File("F:\\4.txt");//用File对象做目录创建文件




//以下方法需要处理异常;可以用消极处理
boolean createNewFile();    创建文件 成功返回 true 文件已存在不创建返回 false
boolean mkdir(); 创建目录
boolean delete(); 删除//删除文件夹时文件夹必须为空
boolean renameTo(); 更改文件名
boolean setReadOnly() 设置文件属性为:只读
 String getName() 返回文件或目录名
boolean endsWith(String s) 判断文件是否以“s”为结尾
boolean exists(); 判断文件对象是否已经存在
boolean isDirectory(); 判断文件对象所代表的是否是目录
boolean isFile(); 判断文件对象所代表的是否是文件  
 String getAbsolutePath(); 获得绝对路径
 File[] listFiles(); 获取目录中的所有内容返回值为File数组
例:
File dir = new File("F:\\CoreJava");
File[] fs = dir.listFiles();
for(File f:fs){
if(f.isFile())System.out.println("文件:"+f.getName());
if(f.isDirectory())System.out.println("目录:"+f.getName());
}


I/O流
流:对象,用来在JVM和外部数据源之间传输数据的通道
流的三种分类:
按照数据传输方向:分为输入流 和 输出流
按照数据传输单位:分为字节流 和 字符流
按功能:    分为节点流 和 过滤流

流一般都是单向传输的;
所有文件都是以字节为单位;
字节流:可以处理所有数据;
字符流: 只能处理文本数据,可以解决字符的编码格式问题
节点流:实际传输数据的流
过滤流:用来给流增加功能
抽象类:
InputStream :字节输入流的父类
OutputStream:字节输出流的父类
子类的类名以父类的类名作为后缀
FileInputStream :文件字节流读入
FileOutputStream:文件字节流输出


FileOutputStream文件字节流  节点流:
//在指定目录下创建文件输出流;需要抛出异常如果文件名不存在则创建文件,如果文件名存在则覆盖之前的文件
//如果在构造方法参数列表中("F:\\a.txt",true) 给两个参数这样写,则代表在文件末尾追加不会覆盖之前的文件;
OutputStream os = new FileOutputStream("F:\\a.txt");
os.wrld(int a):向文件中输入;结果为二进制字符 一次写一个字节
os.write(byte[] bs):将数组中的字节全部输出
os.write(byte[] bs,int a,int b):将数组中从下标a开始输出到下标b结束
os.close() :关闭流,释放资源,确保线程安全
例:
//创建一个字符串
String str ="Hello World";
//String类的方法--将字符串转换成字节数组
byte[] bs = str.getBytes();
os.write(bs);
//输出后,调用方法关闭流
os.close();

FileInputStream文件字节流  节点流:
//创建读入流  指定读取文件
InputStream is = new FileInputStream("a.txt");
int read():从文件中读一个字节  返回-1 为结束
//每次读取数组长度的字节数,直到全部读取完  读取为空时返回-1 需要配合while循环使用
int read(byte[] bs)
int read(byte[] bs,int a,int b):从文件中读取
多个字节,读取bs的一段从下标a位置开始下标b位置
结束返回值为实际读取的字节个数,以-1 为结束
while(true){
int i = is.read();
if(i == -1)break;
System.out.print((char)i);//注意输出时强转成char类型
}
is.close();

使用以上方法需要处理异常完整写法为:
//创建文件内容
public static void main(String[] args){
String str = "Hello World";
//因为局部变量有使用范围所以不能定义在try块中,但是也不能不赋值,所以赋值为null
OutputStream os = null;
try{
//创建输出流  指定输出文件
os = new FileOutputStream("a.txt");
//String类的方法将字符串转换成字节数组
byte[] bs = str.getBytes();
//输出文件内容
os.write(bs);
}catch(IOException e){
//打印异常的调用链

e.printStackTrace();
}finally{
try{
//因为close()方法必须要执行所以放在finally中
//使用close()方法需要处理异常
//为了避免空指针异常所以加一个判断语句
if(os != null)os.close();
}catch(IOException e){
e.printStackTrace();
}
}
}

过滤流
DataInputStream/DataOutputStream 
可以直接读写8种基本类型和String
方法:readUTF()/writeUTF() 读取字符串/写出字符串
BufferedInputStream/BufferedOutputStream   缓冲
方法:flush() :清空缓冲区(在不关闭流的情况下将缓冲区的内容写入文件)


PrintStream 类:可以写八种基本类型   自带缓冲  对象是System.out
PipedInputStream/PipedOutputStream  管道流  用来交换线程间的数据
RandomAccessFile:随机访问文件中的内容(可以自己制定访问位置)


字符的编解码:
编码:将数据转换成字节码的过程
解码:从字节码转换成数据的过程
当编码方式和解码方式不统一时,可能会造成乱码


编码方式
ASCII  英语字符编码 1B(一个字节) 美国人编写
ISO-8859-1
GBK 中国编码 2B
GB2312
Unicode  国际编码  2B
UTF-8  包含所有国家字符(可变长字节) 

桥转换

Reader/Writer 字符流的父类
FileReader/FileWriter 文件字符流 节点流   只能用于文本文件
BufferedReader/PrintWriter  缓冲流  过滤流
InputStreamReader/OutputStreamWriter  桥转换
例:
将一个字节流转换成字符流,这个过程叫做桥转换,通过构造对象完成,在桥转换的时候制定编解码方式
PrintWriter桥转换的默认编解码方式为GBK带缓冲的字节流
OutputStream fos = new FileOutputStream("a.txt");
Writer ow = new OutputStreamWriter(fos);
//JDK5.0 可以用下面这个方法直接创建文本
//PrintWriter out = new PrintWriter("a.txt");
PrintWriter out = new PrintWriter(ow);//过滤器
//将一个字节输入流转换成字符输入流
InputStream fis = new FileInputStream("a.txt");
Reader fr = new InputStreamReader(fis);
BufferedReader in = new BufferedReader(fr);//过滤器
//读取字符串,调用BufferedReader方法,但是调用这个方法要确定
//编写文件时要有换行符,否则程序持续堵塞不会跳出
while(true){
String str = in.readLine();
if(str == null)break;
System.out.println(str);
}
in.close();
//StringBuffer 和StringBuilder  方法完全相同
//线程同步 重量级 线程异步 轻量级


对象序列化
将对象通过流传输
ObjectInputStream/ObjectOutputStream 用来处理对象序列化(过滤流)
但是这个对象必须实现 Serializable 接口成为可序列化对象
Serializable 标记接口 没有任何需要实现的方法
存对象就是存对象的属性,方法可以加载该对象的对应的.class文件
注意:将对象写入文件中时需要覆盖toString方法

用transient修饰的属性叫做临时属性,不参与序列化
如果要在一个文件中写入一个对象的两个不同属性,那么需要更改引用的地址,因为流会记录引用的地址
我们可以用实现Cloneable接口。覆盖clone()方法来克隆一个对象返回同一个引用不同的对象地址
public Object clone(){
try{
return super.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
return null;
}
}

猜你喜欢

转载自blog.csdn.net/yongqi_wang/article/details/80735582