这一篇博文是【大数据技术●降龙十八掌】系列文章的其中一篇,点击查看目录:大数据技术●降龙十八掌
一、 Java IO主要类结构图
二、 Java IO概述
1、 流的概念
在两个程序节点间传输的数据是流。
2、 字节流和字符流的区别
- 字节流处理的单位是字节,长度为8位;字符流处理的单位是字符,长度为2个字节的Unicode字符,长度为16位。
- 字节流可以处理任何格式的数据,比如字符串、图片、视频、音频数据,但是字符流只能处理字符串。
- 字符流最终还是以字节的方式存盘,可以理解为字符流是字节流的封装,处理字符串应该优先考虑使用字符流。
3、 Java IO类结构规划
如上图所示,Java IO里主要分为字节流、字符流,而字节流和字符流都分为输入流和输出流。
(1) 字节流的输入流相关类都派生于InputStream,InputStream是抽象类,在各种不同的应用场景,又派生出不同的子类,如果FileInputStream子类适用于来自于文件的输入。
(2) 字节流的输出流相关类也派生于一个OutputStream抽象父类,各个场景下也派生出什么子类,各个输出流子类与输入流子类是一一对应的。
(3) 同字节流类似,字符流的输入流相关类,也有一个根类Reader,Reader也是个一个抽象类。
(4) 字符流的输出类都继承于根类Writer,各个输出流子类也与输入流的子类一一对应。
三、 字节流
1、 FileInputStream、FileOutputStream
(1) 应用场景
从文件中以二进制方式读取磁盘文件时使用,适合于对文件的简单的读写,当文件是非文本文件时,适合用FileInputStream、FileOutputStream,如果是文本文件,最好用字符流系列。
(2) 常用方法
read() | 从此输入流中读取下一个数据字节。 |
---|---|
read(byte[] b) | 从此输入流中将byte.length个字节的数据读入到b字节数组中 |
read(byte[] b, int off, int len) | 从此输入流中将len个字节数据读入b数组中,写入b数组的开始位置为off。 |
close() | 关闭此输入流并释放此流相关的所有的系统资源。 |
(3) 代码示例
示例1:从文件中一个字节一个字节地读取数据,效率最低。
private static void FileInputStream1() throws FileNotFoundException {
File file = new File("demo.data");
FileInputStream fileInputStream = null;
byte[] array = new byte[(int) file.length()];
try {
fileInputStream = new FileInputStream(file);
int index = 0;
int readval = fileInputStream.read();
while (readval != -1) {
array[index++] = (byte)readval;
readval = fileInputStream.read();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println(new String(array));
}
示例2:以指定大小的字节数为单位,从文件中读取数据,可以批量读取,效率高,尤其在复制大文件时,比较适合,占内存较小。
private static void FileInputStream2() throws FileNotFoundException {
File file = new File("demo.data");
FileInputStream fileInputStream = null;
byte[] tempByte = new byte[3];
byte[] target=new byte[(int)file.length()];
try {
fileInputStream = new FileInputStream(file);
int leng = fileInputStream.read(tempByte);
int currindex=0;
while (leng >0) {
System.arraycopy(tempByte,0,target,currindex,leng);
currindex=currindex+leng;
leng = fileInputStream.read(tempByte);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println(new String(target));
}
示例3:以指定大小的字节数为单位,从文件中分批读取数据,适合操纵小文件。
private static void FileInputStream3() throws FileNotFoundException {
File file = new File("demo.data");
FileInputStream fileInputStream = null;
byte[] target = new byte[(int) file.length()];
try {
int currindex = 0;
int len = 10;
fileInputStream = new FileInputStream(file);
int readleng = fileInputStream.read(target, currindex, len);
while (readleng > 0) {
currindex = currindex + readleng;
int count = (target.length - currindex) < len ? (target.length - currindex) : len;
readleng = fileInputStream.read(target, currindex, count);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println(new String(target));
}
实例四、复制文件
private static void FileInputStream4() throws FileNotFoundException {
File file = new File("demo.data");
File targetfile=new File("demo2.data");
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream=null;
byte[] tempByte = new byte[3];
byte[] target = new byte[(int) file.length()];
try {
fileInputStream = new FileInputStream(file);
fileOutputStream=new FileOutputStream(targetfile);
int leng = fileInputStream.read(tempByte);
int currindex = 0;
while (leng > 0) {
System.arraycopy(tempByte, 0, target, currindex, leng);
fileOutputStream.write(tempByte);
currindex = currindex + leng;
leng = fileInputStream.read(tempByte);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileInputStream.close();
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println(new String(target));
}
2、 FilterInputStream、FilterOutputStream
(4) 应用场景
FilterInputStream 的作用是用来“封装其它的输入流,是抽象类,并为它们提供额外的功能”,是一个修饰类。
它的常用的子类有BufferedInputStream、DataInputStream、PushbakInputStream。
3、 BufferedInputStream、BufferedOutputStream
(5) 应用场景
在内存中提供了一个缓冲区,避免每次读取都进行实际的读操作,提高了效率。BufferedOutputStream是一个修饰后的OutputStream,它对数据流使用了缓冲技术,避免每次发送数据都要进行实际的写操作,可以调用flush()来清空缓冲区。
(6) 常用方法
flush() | 清空缓存中的数据 |
---|---|
write(int b) | 将制定字节写入缓冲输出流 |
write(byte[] b,int off,int len) | 将指定byte数组中的从off个开始的len个字节写入此缓冲输出流。 |
(7) 代码示例
示例:复制文件
public boolean CopyFileToSource(String sourceFilePath, String targetdir, String targetFileName) {
boolean isok = false;
File file = new File(sourceFilePath);
if (!file.exists()) {
return false;
}
file = new File(targetdir);
if (!file.exists() && !file.isDirectory()) {
file.mkdirs();
}
BufferedInputStream inputStream = null;
BufferedOutputStream outputStream = null;
try {
inputStream = new BufferedInputStream(new FileInputStream(new File(sourceFilePath)));
outputStream = new BufferedOutputStream(new FileOutputStream(new File(targetdir + "\\" + targetFileName)));
byte[] temp = new byte[1024];
int count = inputStream.read(temp);
while (count > 0) {
outputStream.write(temp);
count = inputStream.read(temp);
}
isok = true;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inputStream.close();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return isok;
}
4、 DataInputStream、DataOutputStream
(8) 应用场景
可以将各种基本数据类型和String对象格式化输出到流中,应用程序以与机器无关的方式从底层输入流中读取基本Java数据类型,当读取数据时,不必关心这个数值应当是哪种字节编码。
按类型读取和写入数据。
(9) 常用方法
writeBoolean | 写入一个Boolean值 |
---|---|
writeByte | 写入一个字节值 |
writeInt | 写入一个Int值 |
writeUTF | 以UTF-8编码写入一个字符串 |
readBoolean | 读取一个Boolean值 |
readByte | 读取一个字节值 |
readInt | 读取一个Int值 |
readUTF | 以UTF-8编码读取一个字符串 |
(10) 代码示例
public class DataInput {
static List<Person> list = null;
public static void main(String[] args) {
try {
setList();
} catch (ParseException e) {
e.printStackTrace();
}
WriteData();
Person[] plist= ReadData();
}
private static void setList() throws ParseException {
list = new ArrayList<Person>();
Person person = null;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
person = new Person();
person.setId(1);
person.setName("张三");
person.setAge(18);
person.setBrithday(dateFormat.parse("1970-06-28"));
person.setIsjoin(true);
person.setScore(89.5);
list.add(person);
person = new Person();
person.setId(2);
person.setName("李四");
person.setAge(20);
person.setBrithday(dateFormat.parse("1987-12-31"));
person.setIsjoin(false);
person.setScore(90.4);
list.add(person);
person = new Person();
person.setId(3);
person.setName("王五");
person.setAge(22);
person.setBrithday(dateFormat.parse("1984-08-04"));
person.setIsjoin(true);
person.setScore(75);
list.add(person);
}
private static void WriteData() {
DataOutputStream outputStream = null;
try {
outputStream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("DataOutput.dat")));
for (Person p :
list) {
outputStream.writeInt(p.getId());
outputStream.writeUTF(p.getName());
outputStream.writeInt(p.getAge());
outputStream.writeBoolean(p.isjoin());
outputStream.writeDouble(p.getScore());
}
outputStream.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static Person[] ReadData() {
DataInputStream datainput = null;
try {
datainput = new DataInputStream(new BufferedInputStream(new FileInputStream("DataOutput.dat")));
list = new ArrayList<Person>();
while(true)
{
Person person=new Person();
person.setId(datainput.readInt());
person.setName(datainput.readUTF());
person.setAge(datainput.readInt());
person.setIsjoin(datainput.readBoolean());
person.setScore(datainput.readDouble());
list.add(person);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
datainput.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return list.toArray(new Person[0]);
}
}
5、 PrintStream
(11) 应用场景
用于产生格式化输出。
与DataOutputStream区别:
DataOutputStream处理数据的存储;PrintStream处理显示。
(12) 常用方法
print() | 输出一个基本数据类型或者对象 |
---|---|
printIn() | 写入一个行分隔符 |
append | 将制定字符添加到输出流 |
flush | 刷新流的缓存 |
6、 PushbakInputStream
(13) 应用场景
具有“能弹出一个字节的缓冲区”,因此可以将读到的最后一个字符回退。
可以试探性地读取一个字节,看是否符合要求,然后再回退回去一个字节后,再读取字节。
7、 ObjectInputStream、ObjectOutStream
(14) 应用场景
是专门对于对象读写的,要求类已经实现了Serializable接口。
(15) 代码示例
public class ObjectInputDemo {
static List<Person> list = null;
public static void main(String[] args) {
try {
setList();
} catch (ParseException e) {
e.printStackTrace();
}
WriteData();
Person[] pList= ReadData();
}
private static void setList() throws ParseException {
list = new ArrayList<Person>();
Person person = null;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
person = new Person();
person.setId(1);
person.setName("张三");
person.setAge(18);
person.setBrithday(dateFormat.parse("1970-06-28"));
person.setIsjoin(true);
person.setScore(89.5);
list.add(person);
person = new Person();
person.setId(2);
person.setName("李四");
person.setAge(20);
person.setBrithday(dateFormat.parse("1987-12-31"));
person.setIsjoin(false);
person.setScore(90.4);
list.add(person);
person = new Person();
person.setId(3);
person.setName("王五");
person.setAge(22);
person.setBrithday(dateFormat.parse("1984-08-04"));
person.setIsjoin(true);
person.setScore(75);
list.add(person);
}
private static void WriteData() {
ObjectOutputStream outputStream = null;
try {
outputStream = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("data/object.dat")));
for (Person p :
list) {
outputStream.writeObject(p);
}
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static Person[] ReadData() {
ObjectInputStream inputStream = null;
try {
inputStream = new ObjectInputStream(new BufferedInputStream(new FileInputStream("data/object.dat")));
list = new ArrayList<Person>();
while (true) {
Person person = (Person) inputStream.readObject();
list.add(person);
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return list.toArray(new Person[0]);
}
}
8、 PipedInputStream、PipedOutStream
(16) 应用场景
两个进程间读写数据
四、 字符流
11、 InputStreamReader、OutputStreamWriter
(17) 应用场景
这两个是最基础的读写字符流。
(18) 代码示例
实例一:复制文件
public boolean CopyFileToSource(String sourceFilePath, String targetdir, String targetFileName) {
boolean isok = false;
InputStreamReader reader=null;
OutputStreamWriter writer=null;
try {
reader = new InputStreamReader(new BufferedInputStream(new FileInputStream(new File(sourceFilePath))), "GBK");
writer = new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(new File(targetdir + "\\" + targetFileName))));
char[] temp = new char[3];
int i = 0;
while ((i = reader.read(temp)) != -1) {
for (int j = 0; j < i; j++) {
writer.write(temp[j]);
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally {
try {
reader.close();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return isok;
}
12、 FileReader、FileWriter
(1) 应用场景
顾名思义,对文件进行读写时用。
(2) 代码示例
private static void CopyFile() throws IOException {
FileReader reader=new FileReader("src/test/java/Demo.java");
FileWriter writer=new FileWriter("target.java");
char[] temp=new char[2000];
int len;
try {
while ((len=reader.read(temp,0,temp.length))!=-1)
{
writer.write(temp,0,len);
}
writer.flush();
}
catch (Exception ignored){
}
finally {
reader.close();
writer.close();
}
}
13、 BufferedReader、BufferedWriter
(3) 应用场景
是包装流,为了提高效率。
(4) 代码示例
private static void CopyFile2() throws IOException {
BufferedReader reader = new BufferedReader(new FileReader("src/test/java/Demo.java"));
BufferedWriter writer = new BufferedWriter(new FileWriter("target.java"));
String temp;
try {
while ((temp = reader.readLine()) != null) {
writer.write(temp);
writer.newLine();
}
writer.flush();
} catch (Exception ignored) {
} finally {
reader.close();
writer.close();
}
}
14、 PrinterWriter
(1) 应用场景
PrinterWriter用于输出打印对象的格式户形式。
(2) 代码示例
private static void WriterFile(String info) throws FileNotFoundException {
PrintWriter writer=new PrintWriter("target2.java");
try {
writer.write(info);
writer.write('\n');
writer.println(info);
writer.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
writer.close();
}
}
15、 StringReader、StringWriter
(1) 应用场景
对字符串串的处理
(2) 代码示例
private static void transform(String str)
{
StringReader reader=new StringReader(str);
StringWriter writer=new StringWriter();
char[] temp=new char[1024];
int len;
try {
while((len=reader.read(temp,0,temp.length))!=-1)
{
writer.write(new String(temp));
}
writer.flush();
System.out.println(writer.toString());
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
这一篇博文是【大数据技术●降龙十八掌】系列文章的其中一篇,点击查看目录:大数据技术●降龙十八掌