黑马程序员-IO流(核心IO流)
2013-08-05 16:45
260 查看
-----------android培训、java培训、java学习型技术博客、期待与您交流!
------------
(2)这两个读写对象,可用于操作基本数据类型的流对象,包含读写各种基本数据类型的方法
int型 writeInt(int n) int readInt()
boolean型 writeBoolean(boolean b) boolean readBoolean()
double型 writeDouble(double d) double readDouble()
(2)存入的是缓冲区,并未用到键盘和硬盘,所以不需要抛任何IO异常
(3)对象中封装了数组
(4)构造函数:
1)ByteArrayInputStream:在构造函数的时候,需要接受数据源,而且数据源是一个字节数据。
2)ByteArrayOutputStream:在构造函数的时候,不用定义数据目的,因为该对象中已经在内部封装了可变长度的字节数组,这就是数据的目的地
(5)因为两个流对象都是操作的是数据,并没有使用系统资源,所以不用进行close关闭。
(6)其实就是用流的思想操作数组
(7)特有方法:writeTo(OutputStream out) 这个方法用到了字节输出流,有异常存在,需要抛IO异常
代码示例1:
代码示例2:
字符串流对象: StringReader和StringWriter
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();
}
}
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();
}
}
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");
}
}
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();
}
}
}
}
}
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();
}
}
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();
}
}
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();
}
}
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();
}
}
}
}
}
}
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();
}
}
发现这个功能和readLine方法一致。
因为readLine是字符流BufferedReader对象中的方法。而键盘录入是字节流。
能不能将这个字节读取流转成字符流呢?因为BufferedReader只能对字符流进行装饰 。
这就用到了转换流
|---OutputStreamWriter:是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。
------------
一、操作基本数据类型的流对象
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(); } }
相关文章推荐
- 黑马程序员-学习笔记2-IO流之文件复制
- 黑马程序员---IO流-File类,递归
- 黑马程序员——学习日志9IO流
- 黑马程序员 -IO流(上)
- 黑马程序员——学习日记之--IO流学习总结
- 黑马程序员——IO流中的练习
- 黑马程序员——IO流(字节流)
- 黑马程序员——08 IO流的几种读写方式
- 黑马程序员——IO流(一)
- 黑马程序员:DVD管理系统项目之一--核心集合的选择问题
- 黑马程序员_java_IO流
- 黑马程序员——java IO流
- 黑马程序员---Java基础---IO流(三)
- Java基础知识强化之IO流笔记72:NIO之 NIO核心组件(NIO使用代码示例)
- 黑马程序员---IO流总结
- 黑马程序员——Java基础---IO(一)---IO流概述、字符流、字节流、流操作规律
- 黑马程序员---Java基础总结--IO流
- 黑马程序员------IO流文件复制4种代码实现
- 黑马程序员----JAVASE之IO流操作【字节流】
- 黑马程序员_基础_IO流学习笔记_字节流的学习