DAY13
☞☞☞ IO流
输出流代码实现:
分析:将“中国,你好”输出到一个文本文件中,发现更适合用字符流,但是字符流是通过字节流包装得来的,所以先要学习字节流
package cn.edu360;
import java.io.FileOutputStream;
/**
* @author Zhang
*/
public class ClassDemo {
public static void main(String[] args){
FileOutputStream fos = null;
try {
fos = new FileOutputStream("D:\\haha.txt");
byte[] bytes = "中国,你好".getBytes();
fos.write(bytes);
fos.write(bytes, 6, 9);
fos.close();
} catch (Exception e) {
e.printStackTrace();
}finally{
if(null != fos){
try {
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
输入流:
package cn.edu360;
import java.io.FileInputStream;
/**
* @author Zhang
*/
public class ClassDemo {
public static void main(String[] args){
FileInputStream fis = null;
try {
fis = new FileInputStream("D:\\haha.txt");
int i = fis.read();
System.out.println(i);//228
i = fis.read();
System.out.println(i);//184
byte[] b = new byte[1024];
int len = fis.read(b);
System.out.println(len);//22
String result = new String(b, 0, len);
System.out.println(result);//中国,你好,你好
} catch (Exception e) {
e.printStackTrace();
}
}
}
案例展示:
1、把当前项目目录下的a.txt内容复制到当前项目目录下的b.txt中
代码实现:
package cn.edu360;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
* @author Zhang
*/
public class ClassDemo {
public static void main(String[] args){
//先读后写
//文件字节流
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("D:\\haha.txt");
fos = new FileOutputStream("D:\\hehe.txt");
//读的时候,需要定义一个缓冲区容器,一次读取一点
byte[] buf = new byte[1024];
//定义一个变量用于接收每次读取的字节数
int len = -1;
//循环读写
while ((len = fis.read(buf)) != -1) {
fos.write(buf, 0, len);
}
System.out.println("拷贝成功");
} catch (Exception e) {
e.printStackTrace();
}finally{
//先创建的后关闭
if(null != fos){
try {
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if(null != fis){
try {
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
注意:简化上述代码的两种方式:
简化代码如下:
package cn.edu360;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
* @author Zhang
*/
public class ClassDemo {
public static void main(String[] args){
//先读后写
//文件字节流
try(FileInputStream fis = new FileInputStream("D:\\haha.txt");
FileOutputStream fos = new FileOutputStream("D:\\hehe.txt");) {
//读的时候,需要定义一个缓冲区容器,一次读取一点
byte[] buf = new byte[1024];
//定义一个变量用于接收每次读取的字节数
int len = -1;
//循环读写
while ((len = fis.read(buf)) != -1) {
fos.write(buf, 0, len);
}
System.out.println("拷贝成功");
} catch (Exception e) {
e.printStackTrace();
}
}
}
字节缓冲流:
代码实现:
package cn.edu360;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
* @author Zhang
*/
public class ClassDemo {
public static void main(String[] args){
//先读后写
//文件字节流
try (FileInputStream fis = new FileInputStream("D:\\haha.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream("D:\\hehe.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);){
byte[] buf = new byte[1024];
int len = -1;
while((len = bis.read(buf)) != -1){
bos.write(buf,0,len);
//写一次数据就刷一次
bos.flush();
}
System.out.println("复制成功");
} catch (Exception e) {
e.printStackTrace();
}
}
}
字符流:
使用字节流操作文本数据比较麻烦,所以就出现了字符流
字符流=字节流+编码表
编码表:就是一张可以表示文字的码表,我们现实生活中的文字和符号,计算机使不认识的,我们需要给这些文字和符号一个编码,这样计算机存储这些编号就可以了;每个国家都有不同的文字,比如录入中国的文字的编码表有GB2312/GBK/GB18030
代码实现:
package cn.edu360;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
/**
* @author Zhang
*/
public class ClassDemo {
public static void main(String[] args) throws Exception{
FileOutputStream fis = new FileOutputStream("D:\\haha.txt");
OutputStreamWriter osw = new OutputStreamWriter(fis);
osw.write("哈哈,我使用字符流写出的!");
osw.flush();//一定要进行flush,不然没有结果,因为写入的是缓冲区
osw.close();
}
}
代码实现:
package cn.edu360;
import java.io.FileInputStream;
import java.io.InputStreamReader;
/**
* @author Zhang
*/
public class ClassDemo {
public static void main(String[] args) throws Exception{
FileInputStream in = new FileInputStream("D:\\haha.txt");
InputStreamReader isr = new InputStreamReader(in);
char[] cbuf = new char[1024];
int len = isr.read(cbuf);
String content = new String(cbuf, 0, len);
System.out.println(content);
}
}
package cn.edu360;
import java.io.FileWriter;
/**
* @author Zhang
*/
public class ClassDemo {
public static void main(String[] args) throws Exception{
FileWriter fw = new FileWriter("D:\\haha.txt");
fw.write("哈哈,我是用FileWriter写出的");
fw.flush();
fw.close();
}
}
package cn.edu360;
import java.io.FileReader;
/**
* @author Zhang
*/
public class ClassDemo {
public static void main(String[] args) throws Exception{
FileReader fr = new FileReader("D:\\haha.txt");
char[] cbuf = new char[1024];
int len = fr.read(cbuf);
System.out.println(new String(cbuf, 0, len));
}
}
综合案例:
package cn.edu360;
import java.io.FileReader;
import java.io.FileWriter;
/**
* @author Zhang
*/
public class ClassDemo {
public static void main(String[] args) throws Exception{
//先读后写
FileReader fr = new FileReader("D:\\haha.txt");
FileWriter fw = new FileWriter("D:\\hehe.txt");
char[] cbuf = new char[1024];
int len = -1;
while((len = fr.read(cbuf)) != -1){
fw.write(cbuf);
fw.flush();
}
fw.close();
fr.close();
System.out.println("拷贝成功");
}
}
注意事项:在windows中换行分隔符:\r\n;在Linux里面中的换行分隔符:\n
代码实现:
package cn.edu360;
import java.io.BufferedWriter;
import java.io.FileWriter;
/**
* @author Zhang
*/
public class ClassDemo {
public static void main(String[] args) throws Exception{
FileWriter fw = new FileWriter("D:\\hehe.txt");
BufferedWriter bw = new BufferedWriter(fw);
bw.write("哈哈,我是通过缓冲字符输出流写出的");
bw.newLine();
bw.write("哈哈,我是通过缓冲字符输出流写出的");
bw.flush();
bw.close();
}
}
代码实现:
package cn.edu360;
import java.io.BufferedReader;
import java.io.FileReader;
/**
* @author Zhang
*/
public class ClassDemo {
public static void main(String[] args) throws Exception{
FileReader fr = new FileReader("D:\\hehe.txt");
BufferedReader br = new BufferedReader(fr);
String content = br.readLine();
System.out.println(content);//打印一行
content = br.readLine();
System.out.println(content);//打印两行
content = br.readLine();
System.out.println(content);//打印三行
}
}
IO流练习:
1、复制文本
代码实现:
package cn.edu360;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
/**
* @author Zhang
*/
public class ClassDemo {
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new FileReader("D:\\haha.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\xixi.txt"));
String len = null;
while((len = br.readLine()) != null){
bw.write(len);
bw.newLine();
}
bw.close();
br.close();
System.out.println("复制成功");
}
}
2、复制图片
代码实现:
package cn.edu360;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
* @author Zhang
*/
public class ClassDemo {
public static void main(String[] args){
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\mm.jpg"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("E:\\nn.jpg"));){
//自定义缓冲区容器
byte[] buf = new byte[1024];
//自定义变量用于接收每次读取的字节长度
int len = -1;
//循环读取
while((len = bis.read(buf)) != -1){
//读多少写多少
bos.write(buf, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("拷贝成功");
}
}
3、将ArrayList集合中的字符串写入到文本文件中
代码实现:
package cn.edu360;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.ArrayList;
/**
* @author Zhang
*/
public class ClassDemo {
public static void main(String[] args) throws Exception{
//创建ArrayList并添加内容
ArrayList list = new ArrayList();
list.add("javaSe");
list.add("javaEE");
list.add("hadoop");
list.add("张明");
list.add("lili");
//创建缓冲字符流
BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\list.txt"));
for (String result : list) {
bw.write(result);
bw.newLine();
}
bw.close();
System.out.println("添加成功");
}
}
4、从文本文件中读取数据(每一行为一个字符串数据)到集合中,并遍历结合
代码实现:
package cn.edu360;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
/**
* @author Zhang
*/
public class ClassDemo {
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new FileReader("D:\\list.txt"));
ArrayList list = new ArrayList();
String line = null;
while((line = br.readLine()) != null){
list.add(line);
}
br.close();
for (String result : list) {
System.out.println(result);
}
}
}
5、复制单级文件夹
复制单级文件夹中指定文件并修改文件名称
代码实现:
package cn.edu360;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
* @author Zhang
*/
public class ClassDemo {
public static void main(String[] args) throws Exception{
//复制单级文件夹
//1.封装源文件夹的文件对象
File srcFolder = new File("D:\\test123");
//2.封装要拷贝到的文件夹对象
File destFolder = new File("E:\\");
//3.在目标盘符创建一个一模一样的文件夹
destFolder = new File(destFolder, srcFolder.getName());
destFolder.mkdir();
//4.获取源文件夹中所有的子文件对象
File[] files = srcFolder.listFiles();
//遍历所有的子文件对象数组,然后拷贝到目标文件中
for (File srcFile : files) {
//在目标文件夹里面创建一个名字一模一样的文件
File destFile = new File(destFolder, srcFile.getName());
//调用拷贝文件的方法
copyFile(srcFile,destFile);
}
System.out.println("拷贝成功");
}
private static void copyFile(File srcFile, File destFile) {
try(BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile))){
byte[] buf = new byte[1024];
int len = -1;
while((len = bis.read(buf)) != -1){
bos.write(buf, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
6、复制多级文件夹
代码实现:
package cn.edu360;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
* @author Zhang
*/
public class ClassDemo {
public static void main(String[] args) throws Exception{
//1.封装原文件夹对象
File srcFolder = new File("D:\\test123");
//2.封装目标文件夹对象
File destFolder = new File("E:\\");
//调用拷贝文件夹的方法
copyFolder(srcFolder,destFolder);
System.out.println("拷贝成功");
}
private static void copyFolder(File srcFolder, File destFolder) {
//4.判断srcFolder是不是一个标准文件
if(srcFolder.isFile()){
//4.1如果是一个标准文件就直接拷贝
//在目标文件夹中,创建有一个一模一样名字文件
File destFile = new File(destFolder, srcFolder.getName());
copyFile(srcFolder,destFile);
}else {
//4.2如果不是一个标准文件,那么就是一个文件夹
//在目标文件夹中创建一个一模一样的名字子文件夹
destFolder = new File(destFolder, srcFolder.getName());
destFolder.mkdir();
//5.获取原文件夹中所有的子文件对象
File[] files = srcFolder.listFiles();
//6.遍历子文件对象数组,再调用拷贝文件夹的方法
for (File srcFile : files) {
copyFolder(srcFile, destFolder);
}
}
}
private static void copyFile(File srcFile, File destFile) {
try(BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile))){
byte[] buf = new byte[1024];
int len = -1;
while((len = bis.read(buf)) != -1){
bos.write(buf, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
☞☞☞ Java序列化
当两个Java进程进行通信时,发送方需要把这个Java对象转换为字节序列,然后在网络上传送;另一方面,接收方面需要从字节序列中恢复出Java对象
序列化的注意事项:
代码实现:
(1)主代码:
package cn.edu360;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* @author Zhang
*/
public class ClassDemo {
public static void main(String[] args) throws Exception{
//序列化
objectToFile();
//反序列化
fileToObject();
}
private static void fileToObject() throws Exception{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\person.txt"));
Object object = ois.readObject();
System.out.println(object);
}
private static void objectToFile() throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\person.txt"));
oos.writeObject(new Person("张三", 18, "西安"));
oos.close();
System.out.println("成功");
}
}
(2)相关类
package cn.edu360;
import java.io.Serializable;
public class Person implements Serializable{
private String name;
private int age;
private String address;
public Person() {
}
public Person(String name, int age, String address) {
super();
this.name = name;
this.age = age;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "[name=" + name + ", age=" + age + ", address=" + address
+ "]";
}
}
☞☞☞ 内存操作流
package cn.edu360;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;
/**
* @author Zhang
*/
public class ClassDemo {
public static void main(String[] args) throws Exception{
//将一张图片转换成字节数组
byte[] byteArray = imageToByteArray();
//将一个字节数组保存成一张图片
byteArrayToImage(byteArray);
}
private static void byteArrayToImage(byte[] byteArray) throws Exception {
ByteArrayInputStream bais = new ByteArrayInputStream(byteArray);
//将字节数组保存到硬盘上一个文件图片中
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\hehe.jpg"));
//定义一个缓冲区容器
byte[] buf = new byte[1024];
int len = -1;
while((len = bais.read(buf)) != -1){
bos.write(buf, 0, len);
}
bos.close();
System.out.println("保存成功");
}
private static byte[] imageToByteArray() throws FileNotFoundException,
IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\abc.jpg"));
ByteOutputStream baos = new ByteOutputStream();
//自定义缓冲区
byte[] buf = new byte[1024];
int len = -1;
while((len = bis.read(buf)) != -1){
//我们之前是往一个文件中去写,现在改为往一个字节数组中写
baos.write(buf, 0, len);
}
baos.close();
//将字节数组中的字节取出来
byte[] byteArray = baos.toByteArray();
return byteArray;
}
}
注意事项:上述两个跟第一个的案例类似
加密分割和解密组成文件(很重要):
package cn.edu360;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
* @author Zhang
*/
public class ClassDemo {
public static void main(String[] args) throws Exception{
//将一个文件分割成最多四份并且加密
spiltFile();
//将四个文件组合成一张图片
groupFile();
}
private static void groupFile() throws Exception {
//1.创建一个缓冲字节读取流
BufferedInputStream bis = null;
//2.创建字节数组输出流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
for(int i = 0; i < 4; i++){
switch (i) {
case 0:
bis = new BufferedInputStream(new FileInputStream("D:\\temp1.dll"));
//将文件中的字节读取到字节数组中
readByteArray(bis,baos);
break;
case 1:
bis = new BufferedInputStream(new FileInputStream("D:\\temp2.dll"));
readByteArray(bis,baos);
break;
case 2:
bis = new BufferedInputStream(new FileInputStream("D:\\temp3.dll"));
readByteArray(bis,baos);
break;
case 3:
//首先判断第四个文件存不存在
File file = new File("D:\\temp4.dll");
if(file.exists()){
bis = new BufferedInputStream(new FileInputStream("D:\\temp4.dll"));
readByteArray(bis,baos);
}
break;
}
bis.close();
}
//3.将字节数组写出流中的字节数组取出来解密
byte[] byteArray = lockAndKey(baos);
//4.将字节数组保存成一个图片
ByteArrayInputStream bais = new ByteArrayInputStream(byteArray);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\group.jpg"));
byte[] buf = new byte[1024];
int len = -1;
while((len = bais.read(buf)) != -1){
bos.write(buf, 0, len);
}
bos.close();
System.out.println("图片组合成功");
}
private static void readByteArray(BufferedInputStream bis,ByteArrayOutputStream baos) throws Exception {
byte[] buf = new byte[1024];
int len = -1;
while((len = bis.read(buf)) != -1){
baos.write(buf, 0, len);
}
}
private static void spiltFile() throws Exception {
//1.将图片转换成一个加密过后的字节数组
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\车.jpg"));
//2.创建一个字节数组输出流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//3.循环读写
byte[] buf = new byte[1024];
int len = -1;
while((len = bis.read(buf)) != -1){
baos.write(buf, 0, len);
}
bis.close();
//4.将字节数组输出流中的字节数组取出来并加密
byte[] byteArray = lockAndKey(baos);
//5.将字节数组最多分割成四份
//三份分割的文件保存的字节长度
int size = byteArray.length/3;
//6.将每一份数据保存到文件中
BufferedOutputStream bos = null;
for (int i = 0; i < 3; i++) {
switch (i) {
case 0:
bos = new BufferedOutputStream(new FileOutputStream("D:\\temp1.dll"));
//第一次写size字节
bos.write(byteArray, 0, size);//这样写如果文件很大的情况下,内存可能会crash
break;
case 1:
bos = new BufferedOutputStream(new FileOutputStream("D:\\temp2.dll"));
bos.write(byteArray, size, size);
break;
case 2:
bos = new BufferedOutputStream(new FileOutputStream("D:\\temp3.dll"));
bos.write(byteArray, size*2, size);
break;
}
bos.close();
}
//7.判断还有没有剩余的字节
if(size*3 < byteArray.length){
bos = new BufferedOutputStream(new FileOutputStream("D:\\temp4.dll"));
bos.write(byteArray, size*3, byteArray.length-size*3);
bos.close();
}
System.out.println("分隔成功");
}
private static byte[] lockAndKey(ByteArrayOutputStream baos) {
byte[] byteArray = baos.toByteArray();
//加密过程(采用异或)
for (int i = 0; i < byteArray.length; i++) {
byteArray[i] = (byte) (byteArray[i]^61);
}
return byteArray;
}
}