Java中的IO编程实例
一、流的概念和作用
流:代表任何有能力产出数据的数据源对象或者是有能力接受数据的接收端对象。
流的本质:数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
流的作用:为数据源和目的地建立一个输送通道。
Java的IO模型设计非常优秀,它使用Decorator(装饰者)模式,按功能划分Stream,您可以动态装配这些Stream,以便获得您需要的功能。例如,您需要一个具有缓冲的文件输入流,则应当组合使用FileInputStream和BufferedInputStream。
二、流的分类
根据处理数据类型的不同分为:字符流和字节流。
根据数据流向不同分为:输入流和输出流。
三、字节流和字符流有什么区别?
字节流:数据流中最小的数据单元是字节
字符流:数据流中最小的数据单元是字符, Java中的字符是Unicode编码,一个字符占用两个字节。
四、节点流和处理流的区别?
节点流:可以从某节点读数据或向某节点写数据的流。如 FileInputStream
处理流:对已存在的流的连接和封装,实现更为丰富的流数据处理,处理流的构造方法必需其他的流对象参数。如 BufferedReader
节点流和处理流是按照功能不同进行的划分。
节点流,可以从或向一个特定的地方(节点)读写数据。处理流是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。
常用节点流:
- 文 件 FileInputStream FileOutputStrean FileReader FileWriter
文件进行处理的节点流。 - 字符串 StringReader StringWriter 对字符串进行处理的节点流。
- 数组 ByteArrayInputStream ByteArrayOutputStream CharArrayReader CharArrayWriter 对数组进行处理的节点流(对应的不再是 文 件,而是内存中的一个数组)。
- 管道PipedInputStream PipedOutputStream PipedReaderPipedWriter对管道进行处理的节点流。
常用处理流:
- 缓冲流:BufferedInputStrean BufferedOutputStream BufferedReader BufferedWriter增加缓冲功能,避免频繁读写硬盘。
- 转换流:InputStreamReader OutputStreamReader实现字节流和字符流之间的转换。
- 数据流 DataInputStream DataOutputStream 等-提供将基础数据类型写入到文件中,或者读取出来。
五、IO实例1:新建一个文件
public class IO1 {
public static void main(String[] args) throws IOException {
String path = "C:\\Users\\Administrator\\Desktop\\demo\\pic.jpg";
File src = new File(path);
if(!src.exists()){
boolean flag = src.createNewFile();
System.out.println(flag?"新建成功!":"新建失败!");
}
}
}
六、IO实例2:读取文件
public class IO2 {
public static void main(String[] args) throws IOException {
String path = "C:\\Users\\Administrator\\Desktop\\demo\\1.txt";
File src = new File(path);
InputStream inputStream = new FileInputStream(src);
byte[] data = new byte[1024];
int len = 0;
while ((len = inputStream.read(data)) != -1){
System.out.println(new String(data,0, len));
}
inputStream.close();
}
}
66666
66666
66666
66666
66666
66666
七、IO实例3:写出文件
public class IO3 {
public static void main(String[] args) throws IOException {
String path = "C:\\Users\\Administrator\\Desktop\\demo\\2.txt";
File dest = new File(path);
OutputStream outputStream = new FileOutputStream(dest);
String msg = "谁他么买小米!\r\n";
byte[] data = msg.getBytes();
outputStream.write(data);
outputStream.flush();
outputStream.close();
}
}
八、IO实例4:文件拷贝
public class IO4 {
public static void main(String[] args) throws IOException {
File src = new File("C:\\Users\\Administrator\\Desktop\\demo\\1.jpg");
File dest = new File("C:\\Users\\Administrator\\Desktop\\demo\\2.jpg");
copyPic(src, dest);
}
public static void copyPic(File src, File dest) throws IOException {
InputStream inputStream = new FileInputStream(src);
OutputStream outputStream = new FileOutputStream(dest);
byte[] data = new byte[1024];
int len = 0;
while((len = inputStream.read(data)) != -1){
outputStream.write(data, 0, len);
outputStream.flush();
}
outputStream.close();
inputStream.close();
}
}
八、IO实例5:读取纯文本文件
public static void main(String[] args) throws IOException {
File src = new File("C:\\Users\\Administrator\\Desktop\\demo\\1.txt");
Reader reader = new FileReader(src);
char[] data = new char[1024];
int len = 0;
while ((len = reader.read(data)) != -1){
System.out.println(new String(data, 0, len));
}
}
}
66666
66666
66666
66666
66666
66666
九、IO实例6:写出纯文本文件
public class IO6 {
public static void main(String[] args) throws IOException {
File dest = new File("C:\\Users\\Administrator\\Desktop\\demo\\3.txt");
Writer writer = new FileWriter(dest);
String str = "鲁班大师,智商250!";
writer.write(str);
writer.append("唔~不得不承认,有时候肌肉比头脑管用。");
writer.flush();
writer.close();
}
}
十、IO实例7:拷贝纯文本文件
public class IO7 {
public static void main(String[] args) throws IOException {
File src = new File("C:\\Users\\Administrator\\Desktop\\demo\\3.txt");
File dest = new File("C:\\Users\\Administrator\\Desktop\\demo\\4.txt");
Reader reader = new FileReader(src);
Writer writer = new FileWriter(dest);
char[] data = new char[1024];
int len = 0;
while((len = reader.read(data)) != -1){
writer.write(data,0,len);
writer.flush();
}
writer.close();
reader.close();
}
}
十一、IO实例8:文件夹拷贝
递归查找子目录,文件夹则创建,文件则Io流拷贝。
public class IO8 {
public static void main(String[] args) throws IOException {
File src = new File("C:\\Users\\Administrator\\Desktop\\demo\\testCopy");
File dest = new File("C:\\Users\\Administrator\\Desktop\\demo\\testCopy1");
copyDirectory(src, dest);
}
public static void copyDirectory(File src, File dest) throws IOException {
// 若果是文件夹
if (src.isDirectory()) {
// 目标位置也要新建相同名称的文件夹
dest = new File(dest, src.getName());
}
copy(src, dest);
}
public static void copy(File src, File dest) throws IOException {
if (src.isFile()) {
copyFile(src, dest);
}else if(src.isDirectory()){
dest.mkdirs();
for(File sub:src.listFiles()){
copy(sub, new File(dest, sub.getName()));
}
}
}
public static void copyFile(File src, File dest) throws IOException {
Reader reader = new FileReader(src);
Writer writer = new FileWriter(dest);
char[] data = new char[1024];
int len = 0;
while((len = reader.read(data)) != -1){
writer.write(data,0,len);
writer.flush();
}
writer.close();
reader.close();
}
}
十二、IO实例9:Buffered缓冲处理流
(BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter)
其中BufferedReader新增了readLine()方法,BufferedWrite新增了newLine()方法
1、BufferedInputStream和BufferedOutputStream
public class IO9 {
public static void main(String[] args) throws IOException {
File src = new File("C:\\Users\\Administrator\\Desktop\\demo\\timg.jfif");
File dest = new File("C:\\Users\\Administrator\\Desktop\\demo\\timg1.jfif");
InputStream inputStream = new BufferedInputStream(new FileInputStream(src));
OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(dest));
byte[] data = new byte[1024];
int len = 0;
while ((len = inputStream.read(data)) != -1) {
outputStream.write(data, 0, len);
outputStream.flush();
}
outputStream.close();
inputStream.close();
}
}
2、BufferedReader和BufferedWriter
public class IO10 {
public static void main(String[] args) throws IOException {
File src = new File("C:\\Users\\Administrator\\Desktop\\demo\\3.txt");
File dest = new File("C:\\Users\\Administrator\\Desktop\\demo\\5.txt");
BufferedReader bufferedReader = new BufferedReader(new FileReader(src));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(dest));
String line = null;
while((line = bufferedReader.readLine()) != null){
bufferedWriter.write(line);
bufferedWriter.newLine();
}
bufferedWriter.close();
bufferedReader.close();
}
}
十三、IO实例10:转换流
InputStreamReader、OutputStreamWriter
(只能将字节流转换成字符流,指定编解码集,处理乱码)
public class IO11 {
public static void main(String[] args) throws IOException {
File src = new File("C:\\Users\\Administrator\\Desktop\\demo\\3.txt");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(src),"UTF-8"));
String line = null;
while((line = bufferedReader.readLine()) != null){
System.out.println(line);
}
}
}
鲁班大师,智商205!
十四、IO实例11:字节数组流
ByteArrayInputStream(byte[] src)、ByteArrayOutputStream
public class IO12 {
public static void main(String[] args) throws IOException {
read(write());
}
public static void read(byte[] data) throws IOException {
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data);
byte[] outData = new byte[1024];
int len = 0;
while((len = byteArrayInputStream.read(outData)) != -1){
System.out.println(new String(outData));
}
}
public static byte[] write() throws IOException {
String str = "鲁班大师,智商250!";
byte[] data = str.getBytes();
// 为了演示ByteArrayOutputStream,把data写入另一个字节数组
byte[] dest;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byteArrayOutputStream.write(data, 0, data.length);
dest = byteArrayOutputStream.toByteArray();
byteArrayOutputStream.flush();
byteArrayOutputStream.close();
return dest;
}
}
鲁班大师,智商250!
十五、IO实例12:基本数据类型处理流
DataInputStream和DataOutputStream,在Buffered流的外层
(DataInputStream的好处在于在从文件读出数据时,不用费心地自行判断读入字符串时或读入int类型时何时将停止,使用对应的readUTF()和readInt()方法就可以正确地读入完整的类型数据。)
public class IO13 {
public static void main(String[] args) throws IOException {
File dest = new File("C:\\Users\\Administrator\\Desktop\\demo\\2.txt");
write(dest);
read(dest);
}
public static void read(File src) throws IOException {
DataInputStream dataInputStream = new DataInputStream(new FileInputStream(src));
String s = dataInputStream.readUTF();
int i = dataInputStream.readInt();
double v = dataInputStream.readDouble();
System.out.println(s + " " + i + " " + v);
}
public static void write(File dest) throws IOException {
String str = "鲁班大师,智商250!";
int num = 16;
double dnum = 16.66;
DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream(dest));
dataOutputStream.writeUTF(str);
dataOutputStream.writeInt(num);
dataOutputStream.writeDouble(dnum);
dataOutputStream.flush();
dataOutputStream.close();
}
}
鲁班大师,智商250! 16 16.66
补充一:word文档能用字符流操作码?为什么?
不能。因为word文档不是纯文本文件,除了文字还包含很多格式信息。不能用字符流操作。可以用字节流操作。
补充二:InputStream和OutputStream基本特点是?
1、二者都是【字节】输入输出流的抽象父类。
2、以字节为单位处理数据,每次读取/写入一个字节。适合处理二进制文件,如音频、视频、图片等。
3、实现类有FileInputStream和FileOutputStream等。
补充三:Reader和Writer的基本特点是?
二者都是【字符】输入输出流的抽象父类。以字符为单位处理数据,每次读取/写入一个字符(2个字节)。适合处理文本文件。实现类有FileReader和FileWriter等。
补充四:BufferInputStream和BufferedOutputStream的特点是?
BufferInputStream和BufferedOutputStream分别是【缓冲】字节输入输出流,还有【缓冲】字符输入输出流(BufferReader和BufferedWriter)。
缓冲流是处理流,它不直接连接数据源/目的地,而是以一个节点流为参数,在节点流的基础上,提供一些简单操作。
先说不带缓冲的流的工作原理吧:它读取到一个字节/字符,就向用户指定的路径写出去,读一个写一个,所以就慢了。带缓冲的流的工作原理:读取到一个字节/字符,先不输出,等凑足了缓冲的最大容量后一次性写出去,从而提高了工作效率
优点:减少对硬盘的读取次数,降低对硬盘的损耗。
补充五:InputStreamReader和OutputStreamWriter的作用?
二者都是转换流,从字节流转换为字符流,提供一些方便读写【字符】的方法,如InputStreamReader(InputStream in, String charsetName)可以设置解码集
补充六:PrintStream打印流经常用于什么情况?System.out是不是打印流?
1、PrintStream:字节打印流,是OutputStream的实现类。提供了多个重载的print,println等方法,方便地向文本文件中写入数据。
2、System.out是字节打印流(PrintStream的对象),它被称作标准的输出流,输出的目的地是标准的输出设备,即显示器。所以,当我们使用System.out.print或System.out.println时会向屏幕(显示器)输出数据。
补充六:序列化和反序列化指的是?
1、将对象以byte流的形式写入到文件中->序列化;
public class User implements Serializable{ }
User实现了这个接口,代表User这个类的对象具有了将对象以byte流的形式写进文件的功能。
2、将文件中的数据以byte流的形式读到程序中来,->反序列化。
注:很多的对象数据,这些数据中,有些信息我们想让他持久的保存起来,那么这个序列化。就是把内存里面的这些对象给变成一连串的字节描述的过程,常见的就是变成文件。
3、什么情况下需要序列化?
(1)想把的内存中的对象状态保存到一个文件中或者数据库中时候;
(2)想用套接字在网络上传送对象的时候;
(3)想通过RMI传输对象的时候)
transient的作用是?
不希望序列化的属性,可以添加transient关键字;
密码字段是非常敏感的字段,所在在序列化时,不允许写到文件:
private transient String password;
十五、IO实例12:基本数据类型处理流
DataInputStream和DataOutputStream在Buffered流的外层(DataInputStream的好处在于在从文件读出数据时,不用费心地自行判断读入字符串时或读入int类型时何时将停止,使用对应的readUTF()和readInt()方法就可以正确地读入完整的类型数据。)