------ Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
IO流:
package cn.fuxi._06io;
/**
* IO流:
* IO流用来处理设备之间数据的传输,Java对数据的操作是通过流的方式.Java用于
* 操作流的对象都在IO包中.
* 输入流和输出流相对于内存设备而言.
*
* 将外设中的数据读取到内存中:输入.
* 将内存的数据写入到外设中:输出.
*
* 流按操作数据分为两种:字节流和字符流.
*
* 字符流的由来:
* 其实就是:字节流读取文字字节数据后,不直接操作,而是先查指定的编码表,获取对应的文字.
* 再对这个文字经行操作.
* 简单说:字节流+编码表
*
*
* IO常用基类-字符流:
* 字节流的抽象基类:InputStream,OutputStream.
* 字符流的抽象基类:Reader,Writer.
*
* P.S.
* 由着四个类派生出来的子类名称都是以其父类名作为子类名的后缀.
* 如:InputStream的子类FileInputStream.
* 如:reader的子类FileReader.
*/
/*
* 需求:将一些文字存储到硬盘一个文件中.
* 注意:如果要操作文字数据,优先考虑字符流.
* 而且要将数据从内存写到硬盘上,要使用字符输出流:Writer.
* 硬盘的数据基本体现是文件,希望找到一个可以操作文件的Writer:FileWriter.
*
*/
import java.io.*;
public class _01FileWriterDemo {
public static void main(String[] args) {
//创建一个可以往文件中写入字符数据的字符输出流对象
//既然是往一个文件中写入文字数据,那么在创建对象时,就必须明确该文件用于存储数据的目的.
//如果文件不存在,则会自动创建
//如果文件存在,则会被覆盖
try {
FileWriter fw = new FileWriter("IoDemo.txt");
//调用Writer对象中的write(String s)方法,写入数据
//数据暂时被写入到临时存储缓冲区中
fw.write("我不会告诉你我的马甲名字其实就是传说中的传奇查");
//进行刷新,将数据直接写入到目的地中
fw.flush();
//关闭流,关闭资源,在关闭前会先调用flush刷新缓冲中数据到目的地.
fw.close();
} catch (IOException e) {
e.printStackTrace();
}finally{
}
}
}
输出结果:
package cn.fuxi._06io;
/**
* 如果构造函数中加入true,可以实现对文件进行续写.
*/
import java.io.*;
public class _02FileWriterDemo{
public static void main(String[] args){
try {
FileWriter fw = new FileWriter("IoDemo.txt",true);
fw.write("\r\n我传奇查有100种方法让你在IT界混不下去!");
fw.flush();
fw.write("糖宝~");
fw.flush();
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
输出结果:
package cn.fuxi._06io;
/**
* IO流的异常处理方式:为防止代码异常导致流无法关闭,因此在finally中对流经行关闭
*/
import java.io.*;
public class _03FileWriterDemo {
public static void main(String[] args) {
FileWriter fw = null;
try {
fw = new FileWriter("IoDemo.txt",true);
fw.write("啦啦啦~种太阳~");
fw.flush();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
fw.close();
} catch (IOException e) {
throw new RuntimeException("关闭失败");
}
}
}
}
package cn.fuxi._06io;
/**
* 需求:读取一个文件,将读取的字符打印到控制台(使用FileReader)
* 第一种读取方式:使用read()方法读取文本文件数据.
*/
import java.io.*;
public class _04FileReaderDemo {
public static void main(String[] args) {
FileReader fr =null;
try {
fr = new FileReader("IoDemo.txt");
//用Reader中的read()方法读取字符
int ch = 0;
while((ch = fr.read())!=-1){//作为整数读取的字符,范围在 0 到 65535 之间 (0x00-0xffff),如果已到达流的末尾,则返回 -1
System.out.print((char)ch);
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
输出结果:
我不会告诉你我的马甲名字其实就是传说中的传奇查
我传奇查有100种方法让你在IT界混不下去!糖宝~啦啦啦~种太阳~
package cn.fuxi._06io;
/**
* 第二种读取方式:使用read(char[])方法读取文本文件数据.
*/
import java.io.*;
public class _05FileReaderDemo {
public static void main(String[] args) {
FileReader fr = null;
try {
fr = new FileReader("IoDemo.txt");
//使用read(char[])读取文本文件数据
//先穿件字符数组
char[] buf = new char[1024];
int len = 0;
while((len=fr.read(buf))!=-1){
System.out.println(new String(buf,0,len));
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
输出结果:
我不会告诉你我的马甲名字其实就是传说中的传奇查
我传奇查有100种方法让你在IT界混不下去!糖宝~啦啦啦~种太阳~
package cn.fuxi._06io;
/**
* 练习:
* 将d盘的一个文本文件复制到c盘
* 分析: 读取d盘的IoDemo.txt文件中的数据,将这些数据写入到c盘copyText_1.txt文件中.
* 既然是操作文本数据,使用字符流.
* 方式1:使用read()读取文本文件数据.
* 方式2:使用read(char[])读取文本文件数据.
*/
import java.io.*;
public class _06FileReaderTest {
public static void main(String[] args) {
method_1();
method_2();
}
public static void method_1(){
FileReader fr = null;
FileWriter fw = null;
try {
fr = new FileReader("IoDemo.txt");
fw = new FileWriter("Copy_IoDemo.txt");
int ch;
while((ch = fr.read())!=-1){
fw.write(ch);//可以看到,字符型数据传输的本质本质也是数字传输,ch的类型为Int
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void method_2(){
FileReader fr = null;
FileWriter fw = null;
try {
fr = new FileReader("IoDemo.txt");
fw = new FileWriter("Copy2_IoDemo.txt");
char[] ch = new char[1024];
int len = 0;
while((len=fr.read(ch))!=-1){
fw.write(ch,0,len);
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try{
fw.close();
}catch(IOException e){
e.printStackTrace();
}
try{
fr.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
}
输出结果:
package cn.fuxi._06io;
/**
* 字符串缓冲区
* 缓冲区的出现提高了对数据的读写效率.
*
* 对应类:
* BufferedWriter
* BufferedReader
*
* P.S.
* 缓冲区要结合流才可以使用.
*
* 作用:在流的基础上对流的功能进行了增强.提高写入效率,使用缓冲区.
*/
import java.io.*;
public class _07BufferedWriter {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("buff.txt");
//为了提高写入效率,使用字符流的缓冲区.
//创建了一个字符写入流的缓冲区对象,并且指定与要被缓冲的流对象想关联
BufferedWriter bufw = new BufferedWriter(fw);
for (int i = 0; i <= 4; i++) {
//使用缓冲区的写入方法,将数据写入到缓冲区中.
bufw.write("abcdef"+i);
//写入内容换行方法:newLine();
bufw.newLine();
bufw.flush();
}
//使用缓冲区的刷新方法将数据刷入目的地中
bufw.flush();
//关闭缓冲区,其实关闭的就是被缓冲的流对象
fw.close();
}
}
输出结果:
package cn.fuxi._06io;
/**
* 提高读取效率,使用缓冲区
*/
import java.io.*;
public class _08BufferedReader {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("buff.txt");
BufferedReader bf = new BufferedReader(fr);
String line = null;
while((line = bf.readLine())!=null){
System.out.println(line);
}
bf.close();
}
}
输出结果:
abcdef0
abcdef1
abcdef2
abcdef3
abcdef4
package cn.fuxi._06io;
/**
* 字符流缓冲区:
* 写入换行使用BufferedWriter类中的newLine()方法.
* 读取一行数据使用BufferedReader类中的readLine()方法.
*
* br.read():这个read方法是从缓冲区中读取字符数据,所以覆盖了父类中的read方法.
* br.readLine():另外开辟了一个缓冲区,存储的是原缓冲区一行的数据,不包含换行符.
*
* 原理:使用了读取缓冲区的read方法,将读取到的字符进行缓冲并判断换行标记,将标记前
* 的缓冲数据变成字符串返回.
*
*/
import java.io.*;
public class _09BufferedReaderWriter {
public static void main(String[] args) throws Exception{
FileReader fr = new FileReader("buff.txt");
BufferedReader br = new BufferedReader(fr);
FileWriter fw = new FileWriter("Copy_buff.txt");
BufferedWriter bw = new BufferedWriter(fw);
//方式一:一行一行读写
/*
String line = null;
while((line=br.readLine())!=null){
bw.write(line);
bw.newLine();//写一行要换一行,不然会黏在一起
bw.flush();;
}
*/
//方式二:一个一个读写
int ch=0;
while((ch=br.read())!=-1){
bw.write(ch);
bw.flush();//flush不写会空白
}
bw.close();
br.close();
}
}
输出结果:
package cn.fuxi._06io;
/**
* LineNumberReader
* 跟踪行号的缓冲字符输入流.此类定义了方法setLineNumber(int)和getLineNumber();
* 他们可分别用于设置和获取当前行号.
*/
import java.io.*;
public class _10LineNumberReader {
public static void main(String[] args) throws IOException{
FileReader fr = new FileReader("D:\\develop\\workspace\\fuxi4\\src\\cn\\fuxi\\_06io\\_10LineNumberReader.java");
LineNumberReader lnr = new LineNumberReader(fr);
String line = null;
lnr.setLineNumber(100);
while((line = lnr.readLine())!=null){
System.out.println(lnr.getLineNumber()+":"+line);
}
lnr.close();
}
}
输出结果:
101:package cn.fuxi._06io;
102:/**
103: * LineNumberReader
104: * 跟踪行号的缓冲字符输入流.此类定义了方法setLineNumber(int)和getLineNumber();
105: * 他们可分别用于设置和获取当前行号.
106: */
107:import java.io.*;
108:
109:public class _10LineNumberReader {
110:
public static void main(String[] args) throws IOException{
111:
FileReader fr = new FileReader("D:\\develop\\workspace\\fuxi4\\src\\cn\\fuxi\\_06io\\_10LineNumberReader.java");
112:
LineNumberReader lnr = new LineNumberReader(fr);
113:
114:
String line = null;
115:
lnr.setLineNumber(100);
116:
while((line = lnr.readLine())!=null){
117:
System.out.println(lnr.getLineNumber()+":"+line);
118:
}
119:
lnr.close();
120:
}
121:}
package cn.fuxi._06io;
/**
* 对原有类进行了功能的改变,增强.
*/
class Person{
void chiFan(){
System.out.println("吃饭啦!!!");
}
}
//采用装饰的方式增强Person类
//这个类的出现是为了增强Person而出现的
class NewPerson{
private Person p;
NewPerson(Person p){
this.p = p;
}
public void chiFan(){
System.out.println("开胃菜");
p.chiFan();
System.out.println("甜点");
}
}
//采用继承的方式增强Person类
class NewPerson2 extends Person{
public void chiFan(){
System.out.println("来瓶1982的拉菲!");
super.chiFan();
System.out.println("来瓶卡斯特!");
}
}
public class _11ZhuangShiDemo {
public static void main(String[] args) {
Person p = new Person();
p.chiFan();
System.out.println("-------------------");
NewPerson np = new NewPerson(p);
np.chiFan();
System.out.println("-------------------");
NewPerson2 np2 = new NewPerson2();
np2.chiFan();
}
}
/*
*装饰和继承都可以对功能进行拓展,两者之间有何区别呢?
*装饰较为灵活,可以不产生继承关系.
*装饰像缓冲一样可以和具体对象相结合
*可以将缓冲功能进行单独的封装,哪个对象需要缓冲就关联哪个对象
*/
输出结果:
吃饭啦!!!
-------------------
开胃菜
吃饭啦!!!
甜点
-------------------
来瓶1982的拉菲!
吃饭啦!!!
来瓶卡斯特!
package cn.fuxi._06io;
/**
* 首先由一个继承体系:
* Writer
* |--TextWriter:用于操作文本.
* |--MediaWriter:用于操作媒体.
* 如果想要对操作的动作进行效率的提高,按照面向对象,可以通过继承的方式对具体的
* 对象进行功能的拓展,那么就需要加入缓冲技术.
* Writer
* |--TextWriter:用于操作文本.
* |--BufferTextWriter:加入了缓冲技术的操作文本的对象.
* |--MediaWriter:用于操作媒体
* |--BufferMediaWriter:加入了缓冲技术的操作媒体的对象.
* 以上方式并不理想,如果这个体系需要再进行功能扩展,又多了更多流对象.
* 这样就好发现只为了提高功能,导致继承体系越来越臃肿,不够灵活.
*
* 重新思考问题:
* 既然都是加入的同一种技术----缓冲.
* 前一种是让缓冲和自己的流对象相结合.
* 可不可以将缓冲经行单独的封装,哪个对象需要缓冲就将哪个对象和缓冲相关联.
*/
/*
import java.io.*;
class Buffer{
Buffer(TextWriter w){}
Buffer(MediaWriter w){}
}
//简化为
class BufferedWriter extends Writer{
BufferedWriter(Writer){}
}
*/
/**
* Writer
* |--TextWriter:用于操作文本
* |--MediaWriter:用于操作媒体
* |--BufferedWriter:用于提高效率
*
* 可见:装饰比继承更灵活.
* 特点:装饰类和被装饰类都必须所属同一个接口或父类.
*/
package cn.fuxi._06io;
/**
* 练习:
* 自定义一个读取缓冲区类,模拟一个BufferedReader.
* 分析:
* 缓冲区中无非就是封装了一个数组,并对外提供了更多的方法对数组经行访问
* 其实这些方法最终操作的都是数组的角标.
* 缓冲的原理:
* 其实就是从源中获取一批数据到缓冲区中,再从缓冲区中不断的取出一个一个数据.
* 在此次取完后,再从源中继续取一批数据进入缓冲区,当源中的数据被取完时,用-1作为结束标记.
*/
import java.io.*;
class MyBufferedReader{
private Reader r;
//定义一个数组作为缓冲区
private char[] buf = new char[1024];
//定义一个指针用于操作这个数组中的元素,当操作到最后一个元素后,指针应该归零
private int pos = 0;
//定义一个计数器用于记录缓冲区中的数据个数,当该数据减到0;
//就从源中继续获取数据到缓冲区中.
private int count = 0;
MyBufferedReader(Reader r){
this.r = r;
}
//该方法从缓冲区中一次取一个字符
public int myRead() throws IOException{
//从源中获取一批数据到缓冲区中,需要先做判断,只有计数器为0时,才需要
//从源中获取数据.
if(count == 0){
count = r.read(buf);
//每次获取数据到缓冲区后,角标归零
pos = 0;
}
if(count<0)
return -1;
char ch = buf[pos];
pos++;
count--;
return ch;
}
public String myReadLine() throws IOException{
StringBuilder sb = new StringBuilder();
int ch = 0;
while((ch=myRead())!=-1){
if(ch=='\r')
continue;
if(ch=='\n')
return sb.toString();
//从缓冲区读取到的字符,存储到缓冲行的缓冲区中
sb.append((char)ch);
}
if(sb.length()!=0){
return sb.toString();
}
return null;
}
public void myClose() throws IOException{
r.close();
}
}
public class _13BufferTest {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("IoDemo.txt");
MyBufferedReader mbr = new MyBufferedReader(fr);
String line = null;
while((line=mbr.myReadLine())!=null){
System.out.println(line);
}
mbr.myClose();
}
}
输出结果:
我不会告诉你我的马甲名字其实就是传说中的传奇查
我传奇查有100种方法让你在IT界混不下去!糖宝~啦啦啦~种太阳~
package cn.fuxi._06io;
/**
* IO流常用基类-字节流
* 基本操作与字符流类相同.但它不仅可以操作字符,还可以操作其他媒体文件.
*/
import java.io.*;
public class _14FileOutputStream {
public static void main(String[] args) throws IOException {
demo_write();
}
public static void demo_write() throws IOException{
//1.创建字节流输出对象,用于操作文件
FileOutputStream fos = new FileOutputStream("IoDemo.txt",true);
//2.写数据,直接写入到了目的地中
fos.write("ssdlajs".getBytes());
//3.关闭资源~
fos.close();
}
}
输出结果:
package cn.fuxi._06io;
/**
* FileInputStream
*/
import java.io.*;
public class _15FileInputStream {
public static void main(String[] args) throws IOException{
demoRead1();
demoRead2();
demoRead3();
}
//读取方式一:全部一次性用数组读取
public static void demoRead1() throws IOException{
//创建一个读取流对象,和指定文件关联
FileInputStream fis = new FileInputStream("IoDemo.txt");
//打印字符字节大小,不过要少用,文件太大,可能内存溢出
byte[] buf = new byte[fis.available()];
fis.read(buf);
System.out.println(new String(buf));
fis.close();
}
//方式二:推荐使用数组缓冲
public static void demoRead2() throws IOException{
FileInputStream fis = new FileInputStream("IoDemo.txt");
byte[] buf = new byte[1024];
int len = 0;
while((len=fis.read(buf))!=-1){
System.out.println(new String(buf,0,len));
}
fis.close();
}
//方式三:单个字节读取
public static void demoRead3() throws IOException{
FileInputStream fis = new FileInputStream("IoDemo.txt");
InputStreamReader isr = new InputStreamReader(fis);
int ch = 0;
while((ch = isr.read())!=-1){
System.out.print((char)ch);
}
fis.close();
}
}
/*
* FileOutputStream,FileInputStream的flush方法为空,没有任何实现,调用没有意义.
* 字节流的缓冲区,同样是提高字节流的读写效率.
*/
输出结果:
我不会告诉你我的马甲名字其实就是传说中的传奇查
我传奇查有100种方法让你在IT界混不下去!糖宝~啦啦啦~种太阳~ssdlajs
我不会告诉你我的马甲名字其实就是传说中的传奇查
我传奇查有100种方法让你在IT界混不下去!糖宝~啦啦啦~种太阳~ssdlajs
我不会告诉你我的马甲名字其实就是传说中的传奇查
我传奇查有100种方法让你在IT界混不下去!糖宝~啦啦啦~种太阳~ssdlajs
package cn.fuxi._06io;
/**
* 练习:
* 通过几种方式对MP3经行拷贝,比较它们的效率.
*/
import java.io.*;
public class _16Mp3CpoyTest {
public static void main(String[] args) throws IOException{
method_Int();
method_Array();
}
public static void method_Int() throws IOException{
long l1 =System.currentTimeMillis();
FileInputStream fis = new FileInputStream("澤野弘之 - aLIEz (instrumental).flac");
FileOutputStream fos = new FileOutputStream("Copy - aliez.flac");
int ch = 0;
while((ch = fis.read())!=-1){
fos.write(ch);
}
fos.close();
fis.close();
long l2 = System.currentTimeMillis();
System.out.println(l2-l1);
}
public static void method_Array() throws IOException{
long l1 = System.currentTimeMillis();
FileInputStream fis = new FileInputStream("澤野弘之 - aLIEz (instrumental).flac");
FileOutputStream fos = new FileOutputStream("Copy2 - aliez.flac");
byte[] buf = new byte[1024];
int len = 0;
while((len = fis.read(buf))!=-1){
fos.write(buf,0,len);
}
fos.close();
fis.close();
long l2 = System.currentTimeMillis();
System.out.println(l2-l1);
}
}
输出结果:
162982
277