------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
IO流部分
一,IO流概述
1)IO流用来处理设备之间的数据传输
上传文件和下载文件
Java对数据的操作是通过流的方式
Java用于操作流的对象都在IO包中
2)IO流作用:
实现设备之间的数据传输
设备:计算机中的存储设备,硬盘,外接存储设备,另一台计算机
可以在两个计算机之间进行数据的传输
IO流技术可以实现文件的上传和下载
3) IO分类
按照流向分
输入流 Input JAVA程序读取一个数据源
输出流 Output JAVA程序写一个数据到目的中
按照操作的数据分
字节流 操作的是字节数据 字节是计算机中最小的存储单位 8个二进制位 任意文件
字符流 专门用于操作文本文件,人类可以直接识别 , 操作的数据以字符为单位的, 1个字符 16个 二进制位
JDK1.1开始出现了,字符类,方便操作文本文件,读取还是写入都会查询系统默认编码表 GBK
4)IO流中的四大抽象基类
字节输出流抽象基类,用于写文件
java.io.OutputStream
实现子类:FileOutputStream
字节输入流抽象基类,用于读取文件
java.io.InputStream
实现子类:FileInputStream
字符输出流抽象基类,用于写文本文件
java.io.Writer
字符输入流抽象基类,用于读取文本文件
java.io.Reader
二, FileOutputStream的构造方法
FileOutputStream(File file)
FileOutputStream(String name)
字节流写数据的方式
//写入单个字节
public void write(int b)
//写入字节数组
public void write(byte[] b)
//写入字节数组,并指定了长度
public void write(byte[] b,int off,int len)
示例:
/**
* 写入文件
* write(byet[]bytes); 写入字节数组
* write(byet[]bytes,int offset,int length); 写入字节数组,并指定了长度
*
* write(int a ); 写入单个字节
*
* */
public static void method() throws IOException{
FileOutputStream fos = new FileOutputStream("D:\\abc\\456.txt");
//字节数组
fos.write("你好".getBytes(),0,4);
fos.write("你好".getBytes());
//单个字节
fos.write(97);
//关闭输出流
fos.close();
}
}
示例:
/**
* 写入文件时 的异常处理方式
* */
public static void method_1(){
//提升变量fos作用域
//try外面定义变量,里面创建对象
FileOutputStream fos = null;
try{
fos = new FileOutputStream("d:\\abc\\456.txt");
fos.write("bbb".getBytes());
}catch(IOException e){
//让程序停止,抛出运行时期异常
throw new RuntimeException("文件写入失败");
}finally{
System.out.println("s");
try{
if(fos!=null)
fos.close();
}catch(IOException e){
throw new RuntimeException("释放资源失败");
}
}
}
三, FileInputStream的构造方法
InputStream
实现子类:FileInputStream
1) FileInputStream的构造方法
FileInputStream(File file)
FileInputStream(String name)
2) FileInputStream的成员方法
public int read()
public int read(byte[] b)
示例:读取文件中的数据
通常用到循环
int read()方法
返回值为int类型 表示读取到的字符数据
public static void method_3() throws IOException{
FileInputStream fis =
new FileInputStream("d:\\abc\\456.txt");
int x=0;
//循环条件是,read()的返回值是不是-1;
while((x=fis.read())!=-1){
//打印语句中不可再有fis.read();所以要先在循环外定义x
System.out.print((char)x);
}
fis.close();
}
示例:用缓冲数组来 读取文件
用缓冲数组来 读取文件
FileInputStream 读取文本文件,使用数组缓冲(同大口喝水是一个道理)
提高读取效率,用循环读取
read方法,到结尾时 返回-1 停止循环
除此之外返回值为 读到的有效字节数.
public static void method_4() throws IOException {
FileInputStream fis =
new FileInputStream("d:\\abc\\456.txt");
//定义字节数组
byte[] bytes = new byte[5];
//int x变量,保存read方法读取有效字节个数,不等以-1时可以循环
int x = 0;
//read()方法返回值为,读取字节的有效个数
while((x=fis.read(bytes))!=-1){
//输出有效个数
// System.out.print(x);
//将字节数组变为字符串
System.out.print(new String(bytes,0,x));
}
}
四,应用:
IO流实现文件数据的复制
字节流 复制数据(一个字节一个字节复制)
原理:字节输入流,读取数据源文件的字节
字节输出流,将读取到的字节,写入数据目的
FileInputStream 类中的
read()方法
FileOutputStream 类中的
write()方法
public static void method_5() {
//声明类的变量为空,提升作用域
//创建FileInputStream对象 读取数据源
FileInputStream fis = null;
//创建FileOutputStream对象,写数据目的
FileOutputStream fos = null;
try{
//复制源文件
fis = new FileInputStream("d:\\abc\\456.txt");
//指定复制位置
fos = new FileOutputStream("e:\\123.txt");
//读一个字节,写一个字节
int x = 0;
//采用循环
while((x = fis.read())!=-1){
fos.write(x);
}
}catch(IOException e){
throw new RuntimeException("文件复制失败");
}finally{
try{
if(fos!=null)
fos.close();
}catch(IOException e){
throw new RuntimeException("资源关闭失败");
}finally{
try{
if(fis!=null)
fis.close();
}catch(IOException e){
throw new RuntimeException("资源关闭失败");
}
}
}
}
示例:
字节流 复制数据(以字节数组的方式)
效率会提高
public static void method_6(){
//定义子类对象,输入源文件
FileInputStream fis = null;
//写入目的文件
FileOutputStream fos = null;
//处理异常
try{
fis = new FileInputStream("d:\\11.jpg");
fos = new FileOutputStream("e:\\12.txt");
//定义三个位置的字节数组
byte [] b = new byte[3];
//定义获取长度的初始值
int len = 2;
while((len=fis.read(b))!=-1){
//一次写入字节数为len个
fos.write(b,0,len);
}
}catch(IOException e){
throw new RuntimeException("复制文件失败");
}finally{
try{
if(fos!=null)
fos.close();
}catch(IOException e){
throw new RuntimeException("资源关闭失败");
}try{
if(fis!=null)
fis.close();
}catch(IOException e){
throw new RuntimeException("资源关闭失败");
}
}
}
五,四大抽象基类的实现类方法汇总
OutputStream类的方法,写文件的类,里面的方法主要都是写入的方法
write(byte[] bytes)写字节数组
write(byte[] bytes ,int offset,int length)将字节数组一部分写入,开始索引,写几个
write(int a) 写入单个字节
close() 关闭资源,释放资源
InputStream类的方法,读取文件的类,里面的方法主要读取的方法
read(byte[] bytes)读取数据装进字节数组
read(byte[] bytes,int offset,int length)读取数据装进字节数组一部分,开始索引,装几个
read() 读取单个字节
close() 关闭资源
available() 获取读取文件的字节数
Writer类的方法,写文件的,写文本文件,里面的方法主要都是写入的方法
write(char[] ch)写入字符数组
write(char[] ch,int offset,int length)将字符数组一部分写入,开始索引,写几个
write(int a) 写单个字符
write(String s)写入字符串
close() 关闭资源
flush() 刷新流的缓冲
Reader类的方法,读取文件,读取文本文件,里面的方法主要都是读取的方法
read(char[] ch)读取数据装进字符数组
read(char[] ch,int offset,int length)读取数据装进字符数组一部分,开始索引,装几个
read() 读取单个字符
close() 关闭资源
六,字节缓冲流
字节缓冲输出流
BufferedOutputStream
构造方法:
BufferedOutputStream(OutputStream out);
多态 参数 传递子类对象FileOutputStream fos
字节缓冲输入流
BufferedInputStream
构造方法:参数 子类对象 FileInputStream fis
示例:
/*
* 利用字节缓冲区对象,实现文件的复制
*
* */
public static void method_7() {
FileOutputStream fos = null;
FileInputStream fis = null;
try {
// 创建字节输出流对象
fos = new FileOutputStream("e:\\11.jpg");
// 创建字节输入流对象
fis = new FileInputStream("d:\\11.jpg");
// 创建字节流缓冲区对象
BufferedOutputStream bos = new BufferedOutputStream(fos);
BufferedInputStream bis = new BufferedInputStream(fis);
// 定义字节数组
byte[] bytes = new byte[1024];
// 初始长度
int len = 0;
// 先读再写
while ((len = bis.read(bytes)) != -1) {
bos.write(bytes);
}
} catch (IOException e) {
throw new RuntimeException("复制文件失败");
} finally {
try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {
throw new RuntimeException();
}
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
throw new RuntimeException();
}
}
}
七,转换流出现的原因及思想
由于字节流操作中文不是特别方便,所以,java就提供了转换流。
字符流=字节流+编码表。
编码表
由字符及其对应的数值组成的一张表
常见编码表
ASCII/Unicode 字符集
ISO-8859-1
GB2312/GBK/GB18030
BIG5
UTF-8
编码
把看得懂的变成看不懂的
解码
把看不懂的变成看得懂的
示例;
/**
* 字符的解码
* */
public static void method_10() throws Exception {
byte[] b = { -28, -67, -96, -27, -91, -67 };
String s = new String(b, "utf-8");
System.out.println(s);
}
示例:
/**
* 演示 字符的编码
* */
public static void method_9() throws IOException {
// 将字符串转换为字节数组
byte[] b = "你好吗".getBytes("UTF-8");
for (byte b1 : b) {
System.out.println(b1);
}
}
八、 转换流概述
OutputStreamWriter 字符输出流
public OutputStreamWriter(OutputStream out)
public OutputStreamWriter(OutputStream out,String charsetName)
写数据方法:
public void write(int c)
public void write(char[] cbuf)
public void write(char[] cbuf,int off,int len)
public void write(String str)
public void write(String str,int off,int len)
InputStreamReader 字符输入流
public InputStreamReader(InputStream in)
public InputStreamReader(InputStream in,String charsetName)
读数据方法:
public int read()
public int read(char[] cbuf)
示例:
/*
* 转换流对象InputStreamReader,读取文件
* 构造方法的参数为 字节输入流 对象,可以有第二个参数字符串形式的编码表名称
*/
public static void method_11() throws IOException {
FileInputStream fis = new FileInputStream("d:\\123.txt");
// 创建转换流对象,传递字节流对象
InputStreamReader isr = new InputStreamReader(fis);
int len = 0;
while ((len = isr.read()) != -1) {
System.out.print((char) len);
}
isr.close();
}
九、转换流的简化写法
FileWriter
FileReader
示例:
/*
*转换流对象为: OutputStreamWriter InputStreamReader
*转换流对象的简写格式 FileWriter FileReader
*构造方法的参数为 File类对象 或者 String类型的文件名
*如果需要追加写入,构造方法参数中可以写true
*使用转换流简化对象 复制文本文件
* */
public static void method_21() throws IOException{
//创建目的文件
// FileWriter fw = new FileWriter(new File("D:\\123.txt"));
FileWriter fw = new FileWriter("e:\\123.txt");
//创建源文件
FileReader fr = new FileReader("d:\\123.txt");
int len = 0;
while ((len = fr.read())!=-1){
fw.write((char)len);
fw.flush();
}
fw.close();
}
示例:
/*
* 把ArrayList集合中的字符串数据,存到指定文本里;
*思路:遍历集合,获取元素。 用 BufferedWriter 字符缓冲区对象 写入数据
*/
public static void method_15() throws IOException {
// 定义集合
ArrayList<String> al = new ArrayList<String>();
// 添加元素
al.add("abc");
al.add("pok");
al.add("uiy");
// 创建BufferedWriter 字符缓冲区对象
BufferedWriter bw = new BufferedWriter(new FileWriter("d:\\456.txt"));
// 遍历集合 增强for
for (String s : al) {
// 用字符缓冲区对象, 接收字符串;
bw.write(s);
bw.newLine();
bw.flush();
}
bw.close();
}
十、字符缓冲流
BufferedWriter
特有方法:void newLine()
BufferedReade
特有方法:String readLine()
示例:
/*
* 使用 字符缓冲区对象BufferedWriter 写入字符串, 要求有换行
* 思路: newLine()方法 进行换行
*/
public static void method_19() throws Exception {
// 指定写入目的文件
FileWriter fw = new FileWriter(new File("d:\\demo\\345.txt"));
// 与上一行等价
// FileWriter fw = new FileWriter("d:\\demo\\345.txt");
// 创建BufferedWriter对象。参数为 FileWriter对象
BufferedWriter bw = new BufferedWriter(fw);
bw.write("abc");
bw.write("def");
bw.newLine();
bw.write("123");
bw.close();
}
示例:字符缓冲流读取数据
/*
* 从文本中读取一行存进集合中; 并遍历集合
* BufferedReader的构造方法参数为 FileReader
*/
public static void method_16() throws IOException {
// 定义字符缓冲区对象
BufferedReader br = new BufferedReader(new FileReader("d:\\456.txt"));
// 创建集合
ArrayList<String> arr = new ArrayList<>();
String s = null;
// 每次读取一行 , 集合接收一行
while ((s = br.readLine()) != null) {
arr.add(s);
}
for (String st : arr) {
System.out.println(st);
}
}
应用:
复制单级文件夹
思路: 1、复制文件夹到指定位置
2、遍历源文件,获取各文件对象 f,对象调用getName()获取文件名
3、以目的路径+ 文件名为参数 创建文件对象File fi。
4、分别以这两个对象为参数,创建文件输出流对象,和文件输入流对象。
5、循环读、写每一个文件。
public static void method_17() throws Exception {
// 创建源文件对象,并封装路径
File src = new File("d:\\demo");
// 创建目的文件对象; 参数为父路径+ 子路径
File targ = new File("e:", src.getName());
// 完成复制文件夹
targ.mkdirs();
// ======================完成复制文件夹到e盘中
// 初始获取字节有效长度
int len = 0;
// 定义字节缓冲数组
byte[] bytes = new byte[1];
// 遍历文件夹里面的文件,并写进复制后的文件夹里;
// listFiles() 方法返回值为 文件对象数组。
File[] file = src.listFiles();
// f 为存放在数组中的 文件对象 。
for (File f : file) {
// 获取文件名
String fName = f.getName();
// 把路径封装为文件对象, 参数为 父路径 子路径
File fi = new File(targ.getPath(), fName);
// 以文件对象为参数
FileInputStream fis = new FileInputStream(f);
// 以文件对象为参数
FileOutputStream fos = new FileOutputStream(fi);
// 循环获取文件数据
while ((len = fis.read(bytes)) != -1) {
fos.write(bytes, 0, len);
}
// 关闭流
fos.close();
fis.close();
}
}