您的位置:首页 > 职场人生

黑马程序员-IO流(核心IO流)

2013-08-05 16:45 260 查看
-----------android培训java培训、java学习型技术博客、期待与您交流!
------------

一、操作基本数据类型的流对象

1、概述:

(1)操作基本数据类型的流对象:DataInputStream和DataOutputStream

(2)这两个读写对象,可用于操作基本数据类型的流对象,包含读写各种基本数据类型的方法

2、特有方法:

                                  读                                                    写

int型                 writeInt(int n)                               int readInt()

boolean型      writeBoolean(boolean b)         boolean readBoolean()

double型        writeDouble(double d)              double readDouble()

3、代码示例:

import java.io.*;

class DataStreamDemo {
public static void main(String[] args) throws IOException {
writeData();
readData();

}

public static void writeUTFDemo() throws IOException {
DataOutputStream dos = new DataOutputStream(new FileOutputStream(
"utfdate.txt"));

dos.writeUTF("你好");

dos.close();
}

public static void readData() throws IOException {
DataInputStream dis = new DataInputStream(new FileInputStream(
"data.txt"));

int num = dis.readInt();
boolean b = dis.readBoolean();
double d = dis.readDouble();
// 读取基本数据类型。
System.out.println("num=" + num);
System.out.println("b=" + b);
System.out.println("d=" + d);

dis.close();
}

public static void writeData() throws IOException {
DataOutputStream dos = new DataOutputStream(new FileOutputStream(
"data.txt"));

dos.writeInt(234);
dos.writeBoolean(true);
dos.writeDouble(9887.543);// 写入基本数据类型。
dos.close();

}
}

/*output:
num=234
b=true
d=9887.543
*/


二、操作数组和字符串

1、操作字节数组的对象:ByteArrayInputStream和ByteArrayOutputStream

(1)这个对象并没有调用底层资源,所以不用关闭流资源

(2)存入的是缓冲区,并未用到键盘和硬盘,所以不需要抛任何IO异常

(3)对象中封装了数组

(4)构造函数:
1)ByteArrayInputStream:在构造函数的时候,需要接受数据源,而且数据源是一个字节数据。
2)ByteArrayOutputStream:在构造函数的时候,不用定义数据目的,因为该对象中已经在内部封装了可变长度的字节数组,这就是数据的目的地

(5)因为两个流对象都是操作的是数据,并没有使用系统资源,所以不用进行close关闭。

(6)其实就是用流的思想操作数组

(7)特有方法:writeTo(OutputStream out) 这个方法用到了字节输出流,有异常存在,需要抛IO异常

 

代码示例1:

/*
* ByteArrayOutputStream把内存中的数据写到字节数组中,
* 而ByteArrayInputStream又把字节数组中的字节以流的形式读出,
* 从而实现了对同一个字节数组的操作
*/
import java.io.*;

public class Test {
public static void main(String[] args) {
int a = 0;
int b = 1;
int c = 2;
ByteArrayOutputStream bout = new ByteArrayOutputStream();
// 将数据写入输出流的内存缓冲区
bout.write(a);
bout.write(b);
bout.write(c);//利用ByteArrayOutputStream把所有的变量收集到一起,然后一次性把数据发送出去。

// 创建字节数组,并把ByteArrayOutputStream内存缓冲区中的数据以 byte 数组的形式写入字节数组
byte[] shuZu = bout.toByteArray();
for (int i = 0; i < shuZu.length; i++)
System.out.println(shuZu[i]);
System.out.println("***********************");

//ByteArrayInputStream把字节数组shuZu作为其缓冲区数组,并把shuZu中的字节以输入流的形式读出
ByteArrayInputStream bin = new ByteArrayInputStream(shuZu);
while ((b = bin.read()) != -1) {
System.out.println(b);
}
}
}

/*output:
0
1
2
***********************
0
1
2
*/


代码示例2:

import java.io.*;

class ArrayStreamDemo {
public static void main(String[] args) {
// 数据源
ByteArrayInputStream bais = new ByteArrayInputStream(
"ABCDEFF".getBytes());
// 数据目的
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int by = 0;
// 读取和写入数据
while ((by = bais.read()) != -1) {
baos.write(by);
}
System.out.println(baos.size());

System.out.println(baos.toString());

try {
// 方法,此处抛异常,所以上面需要抛出去
baos.writeTo(new FileOutputStream("a.txt"));
} catch (IOException e) {
throw new RuntimeException("写入文件失败");
}

}
}

/*output:
7
ABCDEFF
*/


2、对应的操作字符数组和字符串的对象:

字符数组流对象:CharArrayReader和CharArrayWriter

字符串流对象:   StringReader和StringWriter

三、字节流常见需求:

需求1:在硬盘上创建一个文件并写入信息(字节流写入时没有刷新)

import java.io.*;

public class ByteDemo {

public static void main(String[] args) throws Exception {

FileOutputStream fos = new FileOutputStream("g:\\filestream.txt");
fos.write(97);// 写入一个字节,int:97代表写入char:a
fos.write("也可以写入字节数组".getBytes());// 通常使用此种方式写入,直观!
fos.close();

}
}


需求2:在硬盘已有文件上续写数据(字节流写入时没有刷新)

import java.io.*;

public class ByteDemo {

public static void main(String[] args) throws Exception {

FileOutputStream fos = new FileOutputStream("g:\\filestream.txt", true);
fos.write("创建字节写入流时,传进去一个true参数就可以继续写入信息".getBytes());
fos.close();

}
}


需求3:读取硬盘上的文件

import java.io.*;

public class ByteDemo {

public static void main(String[] args) throws Exception {

FileInputStream fis = new FileInputStream("g:\\filestream.txt");
// 第一种读法:一个字节一个字节的读(此种读法慢)
int ch = 0;
while ((ch = fis.read()) != -1) {
System.out.print((char) ch);
}
System.out.println("over");

// 第二种读法:利用字节数组读(此种读法效率有一定提高)
byte[] buf = new byte[1024];
int len = 0;
while ((len = fis.read()) != -1) {
System.out.print(new String(buf, 0, len));
}
System.out.println("over");
}
}


需求4:拷贝字节文件,如图片或者MP3或者电影

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyPhotos {

/**
* 复制一个图片:
* 1.用字节读取流和图片关联
* 2.用字节写入流对象创建一个图片文件,用于存储获取到得图片数据
* 3.第一种拷贝:不带缓冲流,只用数组做缓冲(慢,还是效率问题)
* 4.通过循环读写,完成数据的存储
*/
public static void main(String[] args) {

FileOutputStream fos=null; //定义字节流
FileInputStream fis=null;

try {

fis=new FileInputStream("g://a.jpg");
fos=new FileOutputStream("h://b.jpg");

//定义数组,作为两个字节流之间的中转站
byte[] buf=new byte[1024];
int len=0;
while((len=fis.read(buf))!=-1){ //循环读写,完成数据的存储

fos.write(buf,0,len);
}

} catch (FileNotFoundException e) {

e.printStackTrace();
} catch (IOException e) {

e.printStackTrace();
}finally{

//释放流资源
if(fis!=null){

try {
fis.close();
} catch (IOException e) {

e.printStackTrace();
}

}

if(fos!=null){
try {
fos.close();
} catch (IOException e) {

e.printStackTrace();
}

}

}

}

}

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyMp3 {

/**
* 复制一个MP3文件 1.用字节读取流和MP3文件关联 2.用字节写入流对象创建一个MP3文件,用于存储获取到得图片数据
* 3.第二种拷贝:带缓冲流,高效 4.通过循环读写,完成数据的存储
*/
public static void main(String[] args) {

FileInputStream fis = null; // 操作数据不是纯文本定义字节流
FileOutputStream fos = null;

BufferedInputStream bufis = null; // 定义缓冲区
BufferedOutputStream bufos = null;

long start = System.currentTimeMillis(); // 复制文件开始时间

try {
fis = new FileInputStream("g://a.mp3"); // 读取,写入文件
fos = new FileOutputStream("h://b.mp3");

bufis = new BufferedInputStream(fis);
bufos = new BufferedOutputStream(fos);

int len = 0;
while ((len = bufis.read()) != -1) {

bufos.write(len);

}

long end = System.currentTimeMillis(); // 复制文件结束时间
System.out.println(end - start + "毫秒"); // 复制文件花费上时间

} catch (FileNotFoundException e) {

e.printStackTrace();
} catch (IOException e) {

e.printStackTrace();
} finally {

// 关闭流资源
if (bufis != null) {
try {
bufis.close();
} catch (IOException e) {

e.printStackTrace();
}
}

if (bufos != null) {
try {
bufos.close();
} catch (IOException e) {

e.printStackTrace();
}

}

}
}

}


四、字符流常见需求(字符流写入时要刷新)

需求1:在硬盘上创建一个文件并写入信息

import java.io.*;

public class CharDemo {

public static void main(String[] args) throws Exception {

// 用字符写入流:FileWriter
FileWriter fw = new FileWriter("g:\\filewriter.txt");
fw.write("输入信息");
fw.write("也可以写入字符数组".toCharArray());
fw.flush();
fw.close();

}
}


需求2:在原有文件上续写数据

import java.io.*;

public class CharDemo {

public static void main(String[] args) throws Exception {

FileWriter fw = new FileWriter("g:\\filewriter.txt", true);
fw.write("还可以续写信息");
fw.write("也可以写入字符数组".toCharArray());
fw.flush();
fw.close();

}
}


需求3:读取硬盘上的文本文件,并将数据打印在控制台

import java.io.*;

public class CharDemo {

public static void main(String[] args) throws Exception {

FileReader fr = new FileReader("g:\\filewriter.txt");
// 第一种读取方法:一个一个字节的读
int ch = 0;
while ((ch = fr.read()) != -1)
// ch = fr.read();
System.out.print((char) ch);
fr.close();

}
}


需求4:拷贝文本文件

(1)用数组做缓冲区

import java.io.*;

public class CharDemo {

/**
* 拷贝文件步骤: 1.创建一个文件B,用于存储读取A文件内数据 2.定义读取流和A文件关联 3.定义数组,作为读取流和写入流之间联系的桥梁
* 4.通过不断的读写完成数据存储 5.关闭流资源
*/
public static void main(String[] args) {

FileWriter fw = null; // 定义写入流
FileReader fr = null; // 定义读取流

try {
fw = new FileWriter("g://hello.txt"); // 创建写入流
fr = new FileReader("h://demo.txt"); // 创建读取流

char[] buf = new char[1024]; // 创建数组作为连接写入流与读取流之间的联系桥梁

int len = 0; // 数组长度变量

while ((len = fr.read(buf)) != -1) { // 将读取的元素存到数组中

fw.write(buf, 0, len); // 将数组中的元素写入到写入流中
}

} catch (IOException e) {
System.out.println("拷贝文件失败");
e.printStackTrace();
} finally {
if (fw != null) {
try {
fw.close(); // 将写入流中的数据冲入到保存区域并关闭写入流
} catch (IOException e) {
System.out.println("关闭写入流失败。。。");
e.printStackTrace();
}
if (fr != null) {
try {
fr.close();
} catch (IOException e) {
System.out.println("关闭读取流失败。。。");
e.printStackTrace();
}
}

}
}

}

}


(2)用装饰类缓冲区

import java.io.*;

public class CharDemo {

public static void main(String[] args) throws Exception {

/*
* 利用缓冲区提高数据读写效率 (无缓冲区就相当于一滴一滴的喝水,有缓冲区就相当于一杯一杯的喝水)
*/
BufferedReader bufr = new BufferedReader(new FileReader(
"g:\\filewriter.txt"));
BufferedWriter bufw = new BufferedWriter(new FileWriter(
"h:\\copyfilewriter.txt"));
String line = null;
while ((line = bufr.readLine()) != null) {
bufw.write(line);
bufw.newLine();
bufw.flush();
}
bufr.close();
bufw.close();

}
}


五、转换流:

1、转换流的引入

键盘录入转成大写输出,并判断over结束的程序中使用了到对字节数据的存储,并对回车符进行判断。

发现这个功能和readLine方法一致。

因为readLine是字符流BufferedReader对象中的方法。而键盘录入是字节流。

能不能将这个字节读取流转成字符流呢?因为BufferedReader只能对字符流进行装饰 。

这就用到了转换流

2、分类:

|---InputStreamReader:是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。

|---OutputStreamWriter:是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。

 

3、代码示例:

步骤1:读取一个键盘录入

import java.io.*;

public class transform {

public static void main(String[] args) throws IOException {
InputStream in = System.in;// 创建一个键盘录入流,流不关则可以一直录入
int by1 = in.read();// 一次读一个字节
int by2 = in.read();// 一次读一个字节
System.out.println((char) by1);// 假设键盘录入的是abcd,则打印a
System.out.println((char) by2);// 假设键盘录入的是abcd,则打印b
in.close();
}

}


步骤2:键盘录入一行数据打印一行数据,如果录入的是over则结束录入

import java.io.*;

public class transform {

public static void main(String[] args) throws IOException {
InputStream in = System.in;
StringBuilder sb = new StringBuilder();
while (true) {
int ch = in.read();
if (ch == '\r')
continue;
if (ch == '\n') {
String line = sb.toString();
if ("over".equals(line))
break;
System.out.println(line.toUpperCase());// 输出大写
sb.delete(0, sb.length());// 清除上一行录入的数据

} else
sb.append((char) ch);
}
in.close();

}

}


步骤3:发现需求2中其实就是读一行的原理,故引入字节通向字符的桥梁:InputStreamReader

import java.io.*;

public class transform {

public static void main(String[] args) throws IOException {
// 为提高效率加入缓冲区:
BufferedReader bufr = new BufferedReader(new InputStreamReader(
System.in));
String line = null;
while ((line = bufr.readLine()) != null) {
if ("over".equals(line))
break;
System.out.println(line.toUpperCase());// 输出大写
}
bufr.close();

}

}


步骤4:键盘录入数据并打印到控制台

import java.io.*;

public class transform {

public static void main(String[] args) throws IOException {
BufferedReader bufr = new BufferedReader(new InputStreamReader(
System.in));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(
System.out));
String line = null;
while ((line = bufr.readLine()) != null) {
if ("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufr.close();
bufw.close();

}

}


步骤5:将键盘录入的数据存储到硬盘文件

/*则只需将(4)中的
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
改为:
BufferedWriter bufw = new BufferedWriter(new FileWriter("g:\\demo.txt"));
*/

import java.io.*;

public class transform {

public static void main(String[] args) throws IOException {

BufferedReader bufr = new BufferedReader(new InputStreamReader(
System.in));
BufferedWriter bufw = new BufferedWriter(new FileWriter("g:\\demo.txt"));
String line = null;
while ((line = bufr.readLine()) != null) {
if ("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufr.close();
bufw.close();
}

}


步骤6:将硬盘文件的数据打印到控制台

/*则只需将(4)中的
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
改为:
BufferedReader bufr = new BufferedReader(new FileReader("g:\\demo.txt"));
即:*/

import java.io.*;

public class transform {

public static void main(String[] args) throws IOException {

BufferedReader bufr = new BufferedReader(new FileReader("g:\\demo.txt"));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(
System.out));
String line = null;
while ((line = bufr.readLine()) != null) {
if ("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufr.close();
bufw.close();

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Java