1. 节点流讲解
常用子类以File(文件)这个类型作为讲解节点流的典型代表
1.1 范例:使用FileInputStream流来读取FileInputStream.java文件的内容
public class TestFileInputStream {
public static void main(String args[]) {
int b = 0;// 使用变量b来装调用read()方法时返回的整数
FileInputStream in = null;
// 使用FileInputStream流来读取有中文的内容时,读出来的是乱码,因为使用InputStream流里面的read()方法读取内容时是一个字节一个字节地读取的,而一个汉字是占用两个字节的,所以读取出来的汉字无法正确显示。
// FileReader in = null;//使用FileReader流来读取内容时,中英文都可以正确显示,因为Reader流里面的read()方法是一个字符一个字符地读取的,这样每次读取出来的都是一个完整的汉字,这样就可以正确显示了。
try {
in = new FileInputStream("D:\\FileInputStream.java");
// in = new FileReader("D:/TestFileInputStream.java");
} catch (FileNotFoundException e) {
System.out.println("系统找不到指定文件!");
System.exit(-1);// 系统非正常退出
}
long num = 0;// 使用变量num来记录读取到的字符数
try {// 调用read()方法时会抛异常,所以需要捕获异常
while ((b = in.read()) != -1) {
// 调用int read() throws Exception方法时,返回的是一个int类型的整数
// 循环结束的条件就是返回一个值-1,表示此时已经读取到文件的末尾了。
// System.out.print(b+"\t");//如果没有使用“(char)b”进行转换,那么直接打印出来的b就是数字,而不是英文和中文了
System.out.print((char) b);
// “char(b)”把使用数字表示的汉字和英文字母转换成字符输入
num++;
}
in.close();// 关闭输入流
System.out.println();
System.out.println("总共读取了" + num + "个字节的文件");
} catch (IOException e1) {
System.out.println("文件读取错误!");
}
}
}
1.2 范例:如果读取的文件内容含有中文,处理方式[不推荐]
public class InputStream01Test {
public static void main(String[] args) throws IOException {
// 1.建立联系
File file = new File("D:" + File.separator + "cy43.txt");
// 2.建立字节流-输入流
InputStream is = null;
try {
if (file.exists()) {
is = new FileInputStream(file);
//2.读取数据,这种循环一定要记住,经常会使用
byte[] b = new byte[4];
int shxt = 0;
while((shxt = is.read(b))!=-1){
System.out.println("shxt="+shxt);
System.out.print(new String(b,0,shxt,"GBK"));//GBK中文支持
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(is!=null){
is.close();
}
}
}
}
1.3 范例: 使用FileOutputStream流往一个文件里面写入数据
public class OutputStream02Test {
public static void main(String[] args) throws IOException {
File file = new File("d:/vip/shxt/cy44.txt");//1.建立联系
//2.判断父路径是否存在
if(!file.getParentFile().exists()){
file.getParentFile().mkdirs();
}
//3.对象上转型
OutputStream os = null;//因为os是局部变量需要显性赋值
try {
os = new FileOutputStream(file,true);//追加数据
//4.执行写入操作
String hello = "\r\n王刚";
//如何换行,请注意 \r\n 是换行
os.write(hello.getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}finally {
//5.关闭资源
if(os!=null){
os.close();
}
}
}
}
2.处理流讲解
2.1 第一种处理流——缓冲流(Buffering)
推荐使用带有缓冲区的,缓冲区(Buffer)就是内存里面的一小块区域,读写数据时都是先把数据放到这块缓冲区域里面,减少io对硬盘的访问次数,保护我们的硬盘。可以把缓冲区想象成一个小桶,把要读写的数据想象成水,每次读取数据或者是写入数据之前,都是先把数据装到这个桶里面,装满了以后再做处理。这就是所谓的缓冲。先把数据放置到缓冲区上,等到缓冲区满了以后,再一次把缓冲区里面的数据写入到硬盘上或者读取出来,这样可以有效地减少对硬盘的访问次数,有利于保护我们的硬盘。
缓存流-测试代码
public class 缓存流_处理字节流_输出流 {
public static void main(String[] args) throws IOException {
// 1.建立联系
File file = new File("D:" + File.separator + "20170325/缓存流.txt");
// 2.判断
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();// 创建文件夹
}
OutputStream os = new FileOutputStream(file);//节点流-字节流
//使用处理流中的缓存流,把内容写到内存当中,为了保护硬盘提高写入的效率
BufferedOutputStream bos = new BufferedOutputStream(os);
String hello="hello world\r\nwukong";
bos.write(hello.getBytes()/*字符串转自己数组*/);
//bos.flush();//强制刷新缓存
bos.close();
}
}
public class 缓存流_处理字节流_输入流 {
public static void main(String[] args) throws IOException {
long start = System.currentTimeMillis();
//复制文件-字节流处理
//节点流-字节流
InputStream is = new FileInputStream(new File("D:/窗外.mp4"));
OutputStream os = new FileOutputStream(new File("E:/aaa.mp4"));
//字节流 进行处理 缓存流
BufferedInputStream bis = new BufferedInputStream(is);
BufferedOutputStream bos = new BufferedOutputStream(os);
//读/写
int len =0;
byte[] b= new byte[1024];
while((len=bis.read(b))!=-1){
bos.write(b, 0, len);
}
is.close();
os.close();
long end = System.currentTimeMillis();
System.out.println((end-start)+"毫秒");
}
}
public class 缓存流_处理字符流_输入输出流 {
public static void main(String[] args) throws IOException {
Writer w = new FileWriter("D:/八戒.txt");
BufferedWriter bw = new BufferedWriter(w);
for(int i=0;i<10000;i++){
bw.write(new Random().nextInt(10000)+"");
bw.newLine();// \r\n
}
Reader r = new FileReader("D:/八戒.txt");
BufferedReader br = new BufferedReader(r);
String str = "";
while((str=br.readLine()/*读取一行数据 \r\n*/)!=null){
System.out.println(str);
}
bw.close();
br.close();
}
}
分析说明
程序的输入指的是把从文件读取到的内容存储到为程序分配的内存区域里面去。
流,什么是流,流无非就是两根管道,一根向里,一根向外,向里向外都是对于我们自己写的程序来说,流分为各种各样的类型,不同的分类方式又可以分为不同的类型,根据方向来分,分为输入流和输出流,根据读取数据的单位的不同,又可以分为字符流和字节流,除此之外,还可以分为节点流和处理流,节点流就是直接和数据源连接的流,处理流就是包在其它流上面的流,处理流不是直接和数据源连接,而是从数据源读取到数据以后再通过处理流处理一遍。
缓冲流也包含了四个类:BufferedInputStream、BufferedOutputStream、BufferedReader和BufferedWriter。流都是成对的,没有流是是不成对的,肯定是一个in,一个out。
2.2 第二种处理流——转换流
非常有用转换流非常的有用,它可以把一个字节流转换成一个字符流,转换流有两种,一种叫InputStreamReader,另一种叫OutputStreamWriter。
InputStream是字节流,Reader是字符流,InputStreamReader就是把InputStream转换成Reader。
OutputStream是字节流,Writer是字符流,OutputStreamWriter就是把OutputStream转换成Writer。
把OutputStream转换成Writer之后就可以一个字符一个字符地通过管道写入数据了,而且还可以写入字符串。我们如果用一个FileOutputStream流往文件里面写东西,得要一个字节一个字节地写进去,但是如果我们在FileOutputStream流上面套上一个字符转换流,那我们就可以一个字符串一个字符串地写进去。
import java.io.*;
public class TestTransform1 {
public static void main(String args[]) {
try {
OutputStreamWriter osw = new OutputStreamWriter(
new FileOutputStream("D:/java/char.txt"));
osw.write("MircosoftsunIBMOracleApplet");// 把字符串写入到指定的文件中去
System.out.println(osw.getEncoding());// 使用getEncoding()方法取得当前系统的默认字符编码
osw.close();
osw = new OutputStreamWriter(new FileOutputStream(
"D:\\java\\char.txt", true), "ISO8859_1");
// 如果在调用FileOutputStream的构造方法时没有加入true,那么新加入的字符串就会替换掉原来写入的字符串,在调用构造方法时指定了字符的编码
osw.write("MircosoftsunIBMOracleApplet");// 再次向指定的文件写入字符串,新写入的字符串加入到原来字符串的后面
System.out.println(osw.getEncoding());
osw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
import java.io.*;
public class TestTransform2{
public static void main(String args[]){
try{
InputStreamReader isr = new InputStreamReader(System.in);
//System.in这里的in是一个标准的输入流,用来接收从键盘输入的数据
BufferedReader br = new BufferedReader(isr);
String s = null;
s = br.readLine();//使用readLine()方法把读取到的一行字符串保存到字符串变量s中去
while(s != null){
System.out.println(s.toUpperCase());//把保存在内存s中的字符串打印出来
s = br.readLine();//在循环体内继续接收从键盘的输入
if(s.equalsIgnoreCase("exit")){
//只要输入exit循环就结束,就会退出
break;
}
}
}catch(Exception e){
e.printStackTrace();
}
}
}
2.3 第三种处理流--数据流[没有怎么使用过]
import java.io.*;
public class TestDataStream{
public static void main(String args[]){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//在调用构造方法时,首先会在内存里面创建一个ByteArray字节数组
DataOutputStream dos = new DataOutputStream(baos);
//在输出流的外面套上一层数据流,用来处理int,double类型的数
try{
dos.writeDouble(Math.random());//把产生的随机数直接写入到字节数组ByteArray中
dos.writeBoolean(true);//布尔类型的数据在内存中就只占一个字节
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
System.out.println(bais.available());
DataInputStream dis = new DataInputStream(bais);
System.out.println(dis.readDouble());//先写进去的就先读出来,调用readDouble()方法读取出写入的随机数
System.out.println(dis.readBoolean());//后写进去的就后读出来,这里面的读取顺序不能更改位置,否则会打印出不正确的结果
dos.close();
bais.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
通过bais这个流往外读取数据的时候,是一个字节一个字节地往外读取的,因此读出来的数据无法判断是字符串还是bool类型的值,因此要在它的外面再套一个流,通过dataInputStream把读出来的数据转换就可以判断了。注意了:读取数据的时候是先写进去的就先读出来,因此读ByteArray字节数组数据的顺序应该是先把占8个字节的double类型的数读出来,然后再读那个只占一个字节的boolean类型的数,因为double类型的数是先写进数组里面的,读的时候也要先读它。这就是所谓的先写的要先读。如果先读Boolean类型的那个数,那么读出来的情况可能就是把double类型数的8个字节里面的一个字节读了出来。
简单看一下,到时候回来看看!!!
2.4 打印流——Print
Paste_Image.pngpublic class 打印流 {
public static void main(String[] args) throws IOException {
// 打印流自带刷新
PrintWriter out = new PrintWriter(new FileWriter("D:/打印流.html"));
out.write("<meta charset='UTF-8'>");
out.write("<h1>悟空</h1>");
out.close();
}
}
2.5 对象流——Object
Paste_Image.pngpublic class Person implements java.io.Serializable/*什么序列化*/{
private int id;
private transient String name;//transient 排除不进行序列化操作
private String sex;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
public class 对象流 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Person p = new Person();
p.setId(1000);
p.setName("林冲");
p.setSex("男");
OutputStream os = new FileOutputStream("D:/person.shxt");
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(p);
InputStream is = new FileInputStream("D:/person.shxt");
ObjectInputStream ois = new ObjectInputStream(is);
Person p1 = (Person)ois.readObject();
System.out.println(p1.getName());
oos.close();
ois.close();
}
}
网友评论