目录
2.3.1、输入流(BufferedInputStream)
2.3.2、输出流(BufferedOutputStream)
IO技术
-
1、基本概念
-
1.1、数据源
data source. 提供原始数据的原始媒介。常见的:数据库、文件、其他程序、内存、网络连接、IO设备。数据源就像水箱,流就像水管中流着的水流,程序就是我们最终的用户。 流是一个抽象、动态的概念,是一连串连续动态的数据集合。
-
1.2、流的概念
文件流:从一端流动到另一端,即从java内存流动到存储介质中。存储介质包括:硬盘文件、数据库与网络等节点(数据源)。记住:一切以java内存为中心。
-
1.3、四大IO抽象类
InputStream/OutputStream和Reader/writer类是所有IO流类的抽象父类,我们有必要简单了解一下这个四个抽象类的作用。然后,通过它们具体的子类熟悉相关的用法。
·InputStream
此抽象类是表示字节输入流的所有类的父类。InputSteam是一个抽象类,它不可以实例化。 数据的读取需要由它的子类来实现。根据节点的不同,它派生了不同的节点流子类 。
继承自InputSteam的流都是用于向程序中输入数据,且数据的单位为字节(8 bit)。
常用方法:
int read():读取一个字节的数据,并将字节的值作为int类型返回(0-255之间的一个值)。如果未读出字节则返回-1(返回值为-1表示读取结束)。
void close():关闭输入流对象,释放相关系统资源。
· OutputStream
此抽象类是表示字节输出流的所有类的父类。输出流接收输出字节并将这些字节发送到某个目的地。
常用方法:
void write(int n):向目的地中写入一个字节。
void close():关闭输出流对象,释放相关系统资源。
· Reader
Reader用于读取的字符流抽象类,数据单位为字符。
int read(): 读取一个字符的数据,并将字符的值作为int类型返回(0-65535之间的一个值,即Unicode值)。如果未读出字符则返回-1(返回值为-1表示读取结束)。
void close() : 关闭流对象,释放相关系统资源。
· Writer
Writer用于写入的字符流抽象类,数据单位为字符。
void write(int n): 向输出流中写入一个字符。
void close() : 关闭输出流对象,释放相关系统资源。
-
2、流
-
2.1、文件字节流
-
2.1.1、输入流(FileInputStream)
* 单字节读取:
*
* 输入流 InputStream
* 此抽象类是表示字节输入流的所有类的超类。
* read() 每次读入一个字节数据,返回读入的数据的int值
*
* 每次都是读入一个字节的数据,效率慢
*
* 批量读取:
*
* 输入流 InputStream
* 解决每次只读入一个字节的问题 read()
* 使用 int read(byte[] b)
* 从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。
* 读入缓冲区的字节总数,如果因为已经到达文件末尾而没有更多的数据,则返回 -1。
public class InputStreamDemo02 {
public static void main(String[] args) {
// 1.建立联系,只是联系
File file = new File("d:/haha.txt");
// 2.选择流 字节流输入
InputStream in = null;
try {
in = new FileInputStream(file);
//3.操作
byte[] bt = new byte[3];
while (in.read(bt) != -1) {
System.out.println(new String(bt));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
// 4.关闭
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
-
2.1.2、输出流(FileOutputStream)
* 03.单字节写入:
* 输出流 OutputStream
* 每次值输出一个数据 write(int)
* 每次只输出一个,不符合需求
* 输入流 InputStream
*
* 04.批量写入:
* 解决一次能够输出多个数据 write(byte[])
* 注意:
* 1.如果目标文件不存在,会自动为你创建
* 2.如果目标文件夹不存在,不会为你自动创建,会抛异常找不到路径
* 3.每次运行输出的内容会进行覆盖,如果想要追加,可以设置第二个参数,如果是true则追加,如果是false是覆盖,默认false
public class OutputStreamDemo03_04 {
public static void main(String[] args) {
// 1.建立联系
File file = new File("D:/haha.txt");
// 2.选择流 文件输出流
OutputStream out = null;
try {
// 以追加形式写出文件 必须为true 否则会覆盖
out = new FileOutputStream(file, true);
// 3.操作
String str = "王杰是真屌\r\n";
// 字符转数组
byte[] bt = str.getBytes();
out.write(bt);
// 强制刷出
out.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
//4.关闭
try {
if(out!=null){
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
-
2.1.3、拷贝
* 文件拷贝
* 1.创建联系--源头,目的地
* 2.选择流--InputStream OutputStream
* 3.读入,写出
* while(len=is.read(car)!=-1){
* os.write(car,0,len);
* }
* 4.强制刷出
* 5.关闭管道
*/
public class CopyFile05 {
public static void main(String[] args) {
// File srcfile = new File("D:/haha.txt");
// File destfile = new File("D:/hehe.txt");
// FileUtil06.copyFile(srcfile, destfile);
// 1.创建联系--数据源,目的地
File srcfile = new File("D:/haha.txt");
File destfile = new File("D:/hehe.txt");
// 2.选择流--文件输入输出流
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream(srcfile);
os = new FileOutputStream(destfile);
// 3.操作--读入
byte[] bt = new byte[128];
int len = 0;
while ((len = is.read(bt)) != -1) {
// 3.操作--写出
os.write(bt, 0, len);
}
// 4.强制刷出
os.flush();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
// 5.先打开的后关闭
try {
if (os != null) {
os.close();
}
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
import java.io.*;
/*
* 文件拷贝工具类
*/
public class FileUtil06 {
/**
* @param srcfile
* 数据源字符串
* @param destfile
* 目的地字符串
*/
public static void copyFile(String srcfile, String destfile) {
copyFile(srcfile, destfile);
}
/**
* @param srcfile
* 数据源对象
* @param destfile
* 目的地对象
*/
public static void copyFile(File srcfile, File destfile) {
// 2.选择流
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream(srcfile);
os = new FileOutputStream(destfile, true);
// 3.操作 读入
// 字节数组
byte[] car = new byte[1024];
int len = 0; // 长度
while ((len = is.read(car)) != -1) {
os.write(car, 0, len);
}
// 4.刷出
os.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 5.先打开的后关闭
try {
if (os != null) {
os.close();
}
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
-
2.2、文件字符流
-
2.2.1、输入流(FileReader)
/*
* 字符输入流读入...
*/
public class ReaderDemo08 {
public static void main(String[] args) {
File file = new File("src/char.txt");
Reader rd =null;
try {
rd= new FileReader(file);
char[] ch = new char[1024];
int len = 0;
while((len=rd.read(ch))!=-1){
System.out.println(new String(ch,0,len));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if (rd!=null) {
rd.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
-
2.2.2、输出流
* 使用字符输出流写出...
* byte[] getBytes(String charsetName)
使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
将字符从此字符串复制到目标字符数组。
public class WriterDemo09 {
public static void main(String[] args) {
File file = new File("src/char.txt");
Writer wt = null;
try {
wt=new FileWriter(file,true);
String str = "qwertyuiio";
//wt.write(str);
char car[]=new char[1024];
str.getChars(0, str.length(), car, 0);
wt.write(car,0,str.length());
wt.flush();
} catch (IOException e) {
e.printStackTrace();
}finally{
//5.关闭
try {
if(wt!=null){
wt.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
-
2.2.3、拷贝
/*
* 使用字符流做文件拷贝...
*/
public class CopyDemo10 {
public static void main(String[] args) {
//1.建立联系
File src=new File("src/char.txt"); //数据源
File dest=new File("src/copy.txt"); //目标
//2.选择流
Reader rd=null;
Writer wr=null;
try {
rd=new FileReader(src);
wr=new FileWriter(dest);
//3.操作
char[] car=new char[1024];
int len=0;
while((len=rd.read(car))!=-1){
wr.write(car,0,len);
}
//强制刷出
wr.flush();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
wr.close();
rd.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//4.关闭
}
}
-
2.3、缓冲字节流
-
2.3.1、输入流(BufferedInputStream)
-
2.3.2、输出流(BufferedOutputStream)
输入:BufferedInputStream
输出:BufferedOutputStream
没有新增方法,可以多态调用
使用和InputSteam一样
public class BufferedI_OCopyDemo11 {
public static void main(String[] args) {
File src = new File("src/char.txt");
File dest = new File("src/copy.txt");
InputStream is = null;
OutputStream os = null;
try {
is = new BufferedInputStream(new FileInputStream(src));
os = new BufferedOutputStream(new FileOutputStream(dest));
int len=0;
byte bt[]=new byte[1024];
while((len=is.read(bt))!=-1){
os.write(bt, 0, len);
}
os.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(os!=null){
os.close();
}
if(is!=null){
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
-
2.4、缓冲字符流
-
2.4.1、输入流(BufferedReader)
-
2.4.2、输出流(BufferedWriter)
字符缓冲流:
输入:BufferedReader
新增:
readLine()读取一行,返回读取到的字符串,否则返回false
newLine()写入一个行分隔符
输出:BufferedWriter
有新增方法,多态调用对子类新增方法不可见.
public class BufferedR_WCopyDemo12 {
public static void main(String[] args) {
// 1,建立联系
File src = new File("src/copy.txt");
File dest = new File("src/newchar.txt");
// 2.流
BufferedReader is = null;
BufferedWriter os = null;
try {
is = new BufferedReader(new FileReader(src));
os = new BufferedWriter(new FileWriter(dest, true));
// 3.操作
int len = 0;
// 新增方法
// String mes=null;
// os.newLine();
// while((mes=is.readLine())!=null){
// os.write(mes);
// }
char[] by = new char[1024];
while ((len = is.read(by)) != -1) {
os.write(by, 0, len);
}
// 4.强制刷出
os.flush();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
// 关闭
if (os != null) {
os.close();
}
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
-
2.5、转换流
-
2.5.1、输入流(InputStreamReader)
-
2.5.2、输出流(OutputStreamWriter)
* 字符转换流:(字节流转成字符流)
* InputStreamReader(InputStream,charset)---Reader
* OutputStreamWriter(OutputStream,charset)---Writer
public class ConvertCopyDemo14 {
public static void main(String[] args) {
// 建立联系
File src = new File("src/newchar.txt");
File dest = new File("src/copy.txt");
// 选择流
BufferedReader rd = null;
BufferedWriter wt = null;
try {
rd = new BufferedReader(new InputStreamReader(
new BufferedInputStream(new FileInputStream(src)), "utf-8"));
wt = new BufferedWriter(new OutputStreamWriter(
new BufferedOutputStream(new FileOutputStream(dest)),
"utf-8"));
// 操作
String msg = null;
while ((msg = rd.readLine()) != null) {
wt.write(msg);
}
//wt.write(rd.readLine());
// 强制刷出
wt.flush();
} catch (UnsupportedEncodingException | FileNotFoundException e) {
System.out.println("456465");
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (rd != null) {
rd.close();
}
if (wt != null) {
wt.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
-
3、转码
-
3.1、乱码
-
3.1.1、编码和解码不同
-
3.1.2、长度丢失
public class ConvertDemo13 {
public static void main(String[] args) throws UnsupportedEncodingException {
// 编码
String s = "中国";
// 解码
byte[] bt = s.getBytes();
System.out.println(new String(bt));// 默认以工作空间的编码格式为准
System.out.println(new String(bt, "gbk"));// 默认以工作空间的编码格式为准
/*
* ISO8859-1 1个字节 UTF-8 3个字节 gbk 2个字节 gb2312 2个字节
*/
System.out.println(s.getBytes("ISO8859-1").length);
System.out.println(s.getBytes("UTF-8").length);
System.out.println(s.getBytes("gbk").length);
System.out.println(s.getBytes("gb2312").length);
// 长度丢失
System.out.println(new String(bt, 0, 4));
}
}