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

黑马程序员——java基础拾遗之IO流(一) 常用类及方法

2014-08-18 12:26 519 查看
-------
android培训、java培训、期待与您交流! ----------


IO流是java很重要的知识点,在这里总结一下IO的一些知识点,常用的类以及用法。

按照操作的数据类型分,IO流分成两种:字节流和字符流。

字节流抽象基类:InputStream,OutputStream;

字符流抽象基类:Reader,Writer;

IO流有很多衍生的类,但是大多以基类名称结尾,可以根据类名是以什么结尾的来区分是那种IO流;

缓冲区:提高数据读写效率。java对文件的读写效率相对比较低,次数越多,程序执行速度越低下,用缓冲区技术目的是减少对文件的读写次数,以此提高IO性能。缓冲区是针对流进行操作的,因此是和流结合使用的。以Buffered开头。

一.字符流常用类

(1)FileWriter类[b]使用示例[/b]

<span style="font-size:14px;">     /**
FileWriter类使用示例
@param args
*/
public static void main(String[] args) {
FileWriter fw = null;
try {
// 此处会抛出异常,D盘下output.txt会被创建,此处true表示不覆盖之前同名的文件,新数据追加在后面
fw = new FileWriter("D:\\output.txt", true);
// 此处会抛出异常,写入流中,不会直接写入文件
fw.write("\n123abc");
} catch (IOException e) {
System.err.println(e.toString());
} finally {
try {
// 为了防止初始化失败(第10行)使此处fw为null出现空指针异常,需要进行空判断
if (null != fw) {
fw.close();//刷新并关闭
}
} catch (IOException e) {
System.err.println(e.toString());
}

}
}</span>


FileWriter 常用方法write()写字符,flush()刷新流程,close()先刷后关。

(2)FileReader类使用示例

文本文件读取示例,读取D盘下一个名字叫Input.txt的文本文件,不用担心换行,换行符会读取到并原样打印出来

<span style="font-size:14px;">/**
FileReader类使用示例
@param args
*/
public static void main(String[] args) {
FileReader fr = null;
char[] ch = new char[1024];
try {
// 读取D盘下的Input.txt文件,不存在抛出文件找不到异常
fr = new FileReader("D:\\Input.txt");
int num = 0;
while ((num = fr.read(ch)) != -1) {// 文件结尾时返回为-1,read(char[] ch)返回读取到的字符数
System.out.println(new String(ch));
}
} catch (IOException e) {
System.err.println("error info:" + e);
} finally {
try {
fr.close();
} catch (IOException e) {
System.err.println("error info" + e);
}

}
}</span>


FileReader 常用方法read:

可以读一个字符,也可以读一个数据,一般都是读数组,如上面的例;

read(char[] ch)返回读取的字符的个数,read()返回读取字符的ASCII码。

字符流通过读取一个数组的方式复制一个文件(比较常用,推荐)

<span style="font-size:14px;">public static void main(String[] args) {
FileWriter fw = null;
FileReader fr = null;
try {
fw = new FileWriter("D:\\MyWorkSpace\\java\\IoDemoTest.txt");
fr = new FileReader("Exception.java");
char[] ch = new char[1024];
int len = 0;
while ((len = fr.read(ch)) != -1) {
fw.write(ch, 0, len);
}
} catch (IOException e) {
throw new RuntimeException("读写失败");
} finally {
if (null != fw) {
try {
fw.close();
} catch (IOException e) {
throw new RuntimeException("流关闭失败");
}
}
if (null != fr) {
try {
fr.close();
} catch (IOException e) {
throw new RuntimeException("流关闭失败");
}
}
}
}
</span>


(3)字符流缓冲区

字符流缓冲区示例,通过字符流缓冲区来复制一个文件

<span style="font-size:14px;">public static void main(String[] args) {
FileWriter fw = null;
FileReader fr = null;
BufferedWriter bufw = null;
BufferedReader bufr = null;
try {
fw = new FileWriter("D:\\BufferedReaderTest.txt");
fr = new FileReader("Exception.java");
bufw = new BufferedWriter(fw);
bufr = new BufferedReader(fr);
String strReadLine = "";
while ((strReadLine = bufr.readLine()) != null) {
bufw.write(strReadLine);
bufw.newLine();
bufw.flush();
}
} catch (IOException e) {
System.err.println("error info:" + e);
} finally {
try {
bufw.close();// 应该分别关这里图省事
bufr.close();
} catch (IOException e) {
System.err.println("error info" + e);
}
}
}</span>


二.字节流常用类

(1)FileInputStream,FileOutputStream类

使用示例,用字节流复制图片

<span style="font-size:14px;">public static void main(String[] args) {
FileOutputStream fos = null;
FileInputStream fis = null;
try {
fis = new FileInputStream("D:\\1.bmp");
fos = new FileOutputStream("D:\\2.bmp");
int len = 0;
byte[] b = new byte[1024];
while ((len = fis.read(b)) != -1) {
fos.write(b, 0, len);
}
} catch (IOException e) {
System.err.println("error info:" + e);
} finally {
if (null != fis) {
try {
fis.close();
} catch (IOException e) {
throw new RuntimeException("文件输入流关闭失败");
}
}
if (null != fos) {
try {
fos.close();
} catch (IOException e) {
throw new RuntimeException("文件输出流关闭失败");
}
}
}
}</span>


FileInputStream 常用方法read(byte[] b)读取字节数组,close()关闭;

FileOutputStream 常用方法write(byte[] b, int off, int len),将字节数组中的固定起始的内容写入文件输出流,close关闭;

区别:FileOutputStream的flush继承自OutputStream,而OutputStream的flush不执行任何操作。因此FileOutputStream不需要执行[b]flush。[/b]

(2)用字节流缓冲区复制Mp3

用法同之前的FileInputStream和FileOutputStream

<span style="font-size:14px;"><span style="font-size:12px;">public static void main(String[] args) {
BufferedInputStream bufIS = null;
BufferedOutputStream bufOS = null;
try {
bufIS = new BufferedInputStream(new FileInputStream("1.mp3"));
bufOS = new BufferedOutputStream(new FileOutputStream("2.mp3"));
int by = 0;
long start = System.currentTimeMillis();
while ((by = bufIS.read()) != -1) {
bufOS.write(by);
}
long end = System.currentTimeMillis();
System.out.println(end - start + "毫秒");
} catch (IOException e) {
throw new RuntimeException("error info" + e);
} finally {
try {
bufIS.close();
} catch (IOException e) {
throw new RuntimeException("error info" + e);
}
try {
bufOS.close();
} catch (IOException e) {
throw new RuntimeException("error info" + e);
}
}
}</span></span>


(3)读取键盘输入流
System.in返回的的是键盘的输入字节流

<span style="font-size:14px;">public static void main(String[] args) {
InputStream in = System.in;
int x = 0;
try {
while ((x = in.read()) != -1) {
System.out.println((char) (x + 1));
}
} catch (IOException e) {
throw new RuntimeException("键盘流读取失败啦");
} finally {
try {
in.close();
} catch (IOException e) {
throw new RuntimeException("键盘流读取失败啦");
}
}
}</span>


上面这种方法已经过时,在java 5以后 已经有新的类可以使用Scanner,Scanner的用法后面继续总结。

三.转换流

用来将字节流转换为字符流,方便使用字符流的readLine()等方法操作数据

(1)InputStreamReader,写入转换流

使用示例

<span style="font-size:14px;">/**
* 读取转换流示例
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
InputStream in = System.in;
// InputStreamReader将字节流转化为了字符流;
InputStreamReader inr = new InputStreamReader(in);
BufferedReader bufr = new BufferedReader(inr);
String str = "";
while ((str = bufr.readLine()) != null) {
if ("over".equals(str)) {
break;
}
System.out.println(str.toUpperCase());
}
}</span>


转化后,可以应用字符流缓冲区的readLine()方法来操作输入流;

(2) OutputStreamWriter,输出转换流

使用示例

<span style="font-size:14px;">    /**
* 输出转换流
* @param args
*/
public static void main(String[] args) {
BufferedReader bufr = new BufferedReader(new InputStreamReader(
System.in));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(
System.out));
String str = "";
try {
while ((str = bufr.readLine()) != null) {
if ("over".equals(str)) {
break;
}
bufw.write(str);
bufw.newLine();// 相当于输出换行符
bufw.flush();
}
} catch (IOException e) {
throw new RuntimeException("转换流失败");
} finally {
try {
bufr.close();
} catch (IOException e) {
throw new RuntimeException("字符读取缓冲区关闭失败");
}
try {
bufw.close();
} catch (IOException e) {
throw new RuntimeException("字符输出缓冲区关闭失败");
}
}
}</span>


上例中展示的是转化后,可以应用字符流缓冲区的newLine()方法来输出跨平台的换行;

注意:OutputStreamWriter可以指定编码表,当涉及编码格式转化时也需要转换流。

注意要点:

1.IO异常的处理,需要格外注意,IO的new方法,读写,流的刷新关闭都会抛出IO异常,

2.流使用以后必须关闭,因此常把流的关闭放在finally代码块中。

3.流的建立遵循先建立引用,后建立对象,目的是将对象建立时候会抛出的异常放在try中捕获,同时不影响finally代码块中针对流对象的关闭。

4.流关闭的时候也会抛出异常,因此在finally中对流的关闭再次捕获异常。

5.对象初始化异常后,finally代码块就不需要再关闭,因此需要对流对象进行空判断。

(是不是很麻烦,习惯就好,这样最保险,养成好习惯最重要)

6.文件路径\\的问题,\表示转义,两个\才能表示\,例如:D:\\java\\1.txt
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: