黑马程序员 IO流

来源:互联网 发布:nginx限制目录访问 编辑:程序博客网 时间:2024/04/29 22:55

java培训、android培训期待与您交流!

IO流
用来处理设备之间的数据传输。按照操作对象来分有两种:字节流与字符流。按流向分为:输入流与输出流
字节流的抽象基类:InputStream,OutputStream
字符流的抽象基类:Reader,Writer
由这四个类派生出来的子类名称都是以父类名作为子类名的后缀
字符流:FileReader;FileWriter;BufferedReader;BufferedWriter
字节流:FileInputStream;FileOutputStream;BufferedInputStream;BufferOutputStream
转换流:字符流与字节流的相互转换
演示:键盘录入,要求要录入的字符转成大写的字符串
import java.io.*;
class IoDemo
{
public static void main(String[] args)throws IOException
{
readIn(); //调用方法

}
public static voidreadIn()throws IOException
{
InputStream in = System.in; //开启键盘录入字节
//需要将读取到的每一个字节进行临时储存,也就需要一个容器:StringBuilder
StringBuilder sb = new StringBuilder();
while(true)
{
int ch = in.read();
if(ch==`\r`)
continue;
if(ch==`\n`)
{
String s = sb.toString(); //将录入的字节转成字符串
if("over".equals(s))
break;
System.out.println(s.toUpperCase()); //将字符串转成大写
sb.delete(0,sb.length()); //当输入一次就删除一次
}
else
sb.append((char)ch);

}
}

}
这种方法效率低下!
改写:
import java.io.*;
class IoDemo
{
public static void main(String[] args)throws IOException
{
InputStream in = System.in; //开启键盘录入字节
InputStreamReader isr = new InputStreamReader(in); //将字节流转成字符流,也即桥梁
BufferedReader bufr = new BufferReader(isr); //将字符扔进字符流缓冲区
String line = null;
while((line=bufr.readLine())!=null)//如果字符长度不为null
{
if("over".equals(line)) //如果输入的是over则结束
break;
System.out.println(line.toUpperCase()); //将字符串转成大写

}
bufr.close();

}

}
这种书写太痛苦!
优化:
import java.io.*;
class IoDemo
{
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.close(); //每写一次就刷一次
}
bufw.close();//关流
bufr.close();//关流
}
}

在实际开发中,一般的,我们需要将字节写入一个文件中。其实,只需要稍作修改就行!
import java.io.*;
class IoDemo
{
public static void main(String[] args)throws IOException
{
//读取键盘输入,按照一行的形式记录
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
//将字符串变成字节打印到控制台上
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
//将字节打印到指定的文件中
bufw = new BufferedReader(new OutputStreamWriter(new FileOutputStream("abc.java")));//创建一个abc.java文件。并将字节打印在该文件中
String line = null;
while((line=bufr.readLine())!=null) //当读取的字符不为空时
{
if("over"equals(line))
break;
bufw.write(line.toUpperCase()); //将写入的字符串转成大写
bufw.newLine(); //换行
bufw.close(); //没写一次就刷一次
}
bufw.close();//关流
bufr.close();//关流

}
}

再对上面的代码进行稍微改写,可以实现文件的复制!
import java.io.*;
class IoDemo
{
public static void main(String[] args)throws IOException
{
//读取键盘输入,按照一行的形式记录
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
//读取一个文本
bufr = new BufferedReader(new InputStreamReader(new FileInputStream("readIn.java"))); //读取一个readIn.java文件
//将字符串变成字节打印到控制台上
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
//将字节打印到指定的文件中
bufw = new BufferedReader(new OutputStreamWriter(new FileOutputStream("abc.java")));//创建一个abc.java文件。并将字节打印在该文件中
String line = null;
while((line=bufr.readLine())!=null) //当读取的字符不为空时
{
if("over"equals(line))
break;
bufw.write(line.toUpperCase()); //将写入的字符串转成大写
bufw.newLine(); //换行
bufw.close(); //每写一次就刷一次
}
bufw.close();//关流
bufr.close();//关流

}
}
流的操作规律:

1,明确数据源和数据目的(汇)
数据源:InputStream Reader
数据目的:OutputStream Writer

2,操作的数据是否是纯文本数据?
是文本数据:Reader Writer
不是文本数据:InputStream OutputStream

数据源,是文本数据:Reader
数据目的,是文本数据:Writer

数据源,不是文本数据:InputStream
数据目的,不是文本数据:OutputStream

在前两部,终于可以明确具体的体系了。
3,明确具体的设备。
数据源:键盘(System.in) 硬盘(File) 内存(数组)
数据目的:控制台(System.out) 硬盘(File) 内存(数组)


4,是否需要其他功能呢?
比如,最常见的功能,是否需要提高效率?
是,就要使用缓冲区。Buffer


怎么将这四点进行实际应用呢?

1,需求:复制一个文件文件。
原理:读取源文件的数据,并将其写入到目的文件中。
1,
数据源:InputStream Reader
数据目的:OutputStream Writer

2,
是不是纯文本。是!
数据源:Reader
数据目的:Writer
3,
数据源:设备:硬盘(File)。FileReader
数据目的:设备,硬盘(File)FileWriter

FileReader fr = new FileReader("a.txt");
FileWriter fw = new FileWriter("b.txt");

4,高效!需要使用Buffer

BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bufw = new BufferedWriter(new FileWriter("b.txt"));


--------------------------
2,需求:将键盘录入的数据,存储到文件中。
1,
数据源:InputStream Reader
数据目的:OutputStream Writer
2,
是纯文本。
数据源:Reader
数据目的:Writer

3,
数据源设备:键盘(System.in)
数据目的设备:硬盘(File)
因为键盘对应的字节流,因为是文本数据,所以用字符流操作更为方便。
所以,就要将字节流转换成字符流。这里就需要用到转换流。
InputStreamReader isr= new InputStreamReader(System.in);
FileWriter fw= new FileWriter("a.txt");

4 高效!
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new FileWriter("a.txt"));

------------------------

3,将硬盘上文本文件的数据打印到控制台。
1,
数据源:InputStream Reader
数据目的:OutputStream Writer
2,
是纯文本
数据源:Reader
数据目的:Writer
3,
数据源设备:硬盘 (File) FileReader
数据目的设备:控制台(System.out).

因为控制台是字节输出流,既然数据目的选择了Writer。就希望将字符流转成字节流。
用到了转换流。OutputStreamWriter

FileReader fr = new FileReader("a.txt");
OutputStreamWriter osw = new OutputStreamWriter(System.out);

4,高效!
BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));

BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));

--------------------------

4,将键盘录入的数据打印到控制台。
1,
数据源:InputStream Reader
数据目的:OutputStream Writer
2,
是纯文本呢
数据源:Reader
数据目的:Writer
3,
数据源设备:键盘(System.in)
数据目的设备:控制台(System.out).

因为键盘对应的字节流,因为是文本数据,所以用字符流操作更为方便。
所以,就要将字节流转换成字符流。这里就需要用到转换流。

因为控制台是字节输出流,既然数据目的选择了Writer。就希望将字符流转成字节流。
用到了转换流。OutputStreamWriter

InputStreamReader isr = new InputStreamReader(System.in);
OutputStreamWriter osw = new OutputStreamWriter(System.out);

4,高效!。
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));

BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));

----------------------------------


5,将数据按照指定的编码形式存到文件中。

1.
该需求中没有流对象所关联的源,数据源仅仅是一个字符串。
数据目的:OutputStream Writer
2,是否是纯文本,是。
数据目的:Writer

3,
数据目的的设备:硬盘(File)FileWriter

FileWriter fw = new FileWriter("a.txt");

4,高效!
BufferedWriter bufw = new BufferedWriter(new FileWriter("a.txt"));

这样已经可以完成一个数据的文件存储。
但是并没有完成指定的编码形式的执行。

对于中文而言,它是需要指定编码表的。
其实在FileWriter对象中就有编码表。使用的是本机默认的字符编码(GBK)
要想指定就需要用FileWriter的父类转换流 OutputStreamWriter。
转换流在构造时是可以指定具体编码的,这也是转换流由来的原因。

OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"),"utf-8");

高效!
BufferedWriter bufw =
new BufferedWriter(new OutputStreamWriter(new FileOutputStream("a.txt"),"utf-8"));
file类
import java.io.*;
import java.util.*;
import java.text.*;
/*
File类的常见功能。

1,获取。
获取文件名。
获取文件路径。
获取文件目录。
获取文件的大小。


2,
创建,
删除。

3,判断。
是否是文件。
是否是目录。
是否是存在。


4,重命名。
renameTo


*/

class FileDemo
{
public static void sop(String str)
{
System.out.println(str);
}
public static void main(String[] args) throws IOException
{
method_5();
}

public static void method_5()
{
File f1 = new File("c:\\haha.bmp");
File f2 = new File("d:\\2.bmp");

f1.renameTo(f2);
}
public static void method_4()throws IOException
{
File f = new File("c:\\abc");

f.createNewFile();
//f.mkdir();

sop("isFile:"+f.isFile());
sop("isDir :"+f.isDirectory());
sop("exists:"+f.exists());

/*
要判断一个file对象是文件或者目录,需要先判断这个file对象封装的内容是否存在。
*/

File file = new File("c:\\FileSplitDemo.java");

long l = file.lastModified();

sop("l:"+l);
Date d = new Date(l);

DateFormat format = DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG);
String time = format.format(d);
sop("time:"+time);
}

public static void method_3()throws IOException
{
File f = new File("a.txt");
//boolean b = f.createNewFile();//会将指定的文件创建到指定的目录下,但是如果该文件已经存在,则不创建。
//输出流,如果要操作的文件不存在,会先创建该文件,用于存储数据,
//如果操作的文件存在,会将该文件覆盖。
//如果给输出流的构造函数中传递了一个boolean参数true,会该文件进行数据的续写。


sop("create:"+b);

boolean b = f.delete();
sop("delete:"+b);

File dir = new File("c:\\abc");
//创建文件夹。
//dir.mkdir();

//sop("dir delete:"+dir.delete());//要删除文件夹,必须保证该文件夹中是没有任何内容。

File dir1 = new File("c:\\abc\\qq\\aa\\kk\\zz\\q\\e");

//dir1.mkdirs();

//sop("dir1:"+dir1.delete());

}

public static void method_2()
{
File file = new File("gbk.txt");
sop("getName:"+file.getName());
sop("getPath:"+file.getPath());
sop("getAbsolutePath:"+file.getAbsolutePath());
sop("getParent:"+file.getParent());//如果封装的内容中没有指定父目录返回null。
sop("length:"+file.length());//获取文件的字节数。

}

//文件对象的建立。
public static void method_1()
{
File f = new File("c:\\a.txt");//将a.txt文件封装成了对象。 这个a.txt文件可以是存在的,也可是不存在。

File f1 = new File("c:\\","a.txt");

File dir = new File("c:\\");

File f2 = new File(dir,"a.txt");

File f3 = new File("c:"+File.separator+"abc"+File.separator+"a.txt");//不同的系统平台对目录分隔符是有区别的。


}
}

Propertier集合
是map集合,是Hashtable的子
特点:储存的键值对都是String类型
通常用于键值对形式的配置文件信息
它的最大功能在于可以和IO技术相关联,可以存储从内存意外的设备上读取的数据,并可以将集合中的数据存储到指定的设备上,比如硬盘上。
演示基本的存储与取出方式:
import java.io.*;
import java.util.*;
class PropertiesDemo
{
public static void main(String[] args)
{
show();
}
public static void show()
Properties prop = new Properties();
//存储元素,使用setProperty()方法来存储键值对
prop.setProperty("lisi","20");
prop.setProperty("lisi","21");
/* Set<String> nameSet = prop.stringPropertyName();使用stringPropertyName()方法来取出元素,并将集合转成Set集合
for(String name : nameSet) //使用高级for语句来遍历
{
System.out.println(name+":"prop.getProperty(name));
}
/*
}
需要注意的是,其中的注释部分可以用prop.load(System.out);来代替!
将该集合与流联系起来,可以将硬盘上的信息加载到集合中去。
演示:
import java.io.*;
import java.util.*;
class PropertiesDemo
{
public static void main(String[] args)
{
show();
}
public static void show()
{
Properties prop = new Properties();
File file = new File("user.java"); //创建一个文件对象,一防止硬盘中不存在这个文件时,系统会抛出异常
if(!file.exzists())
{
System.out.println("要读取的文件不存在!");
return;
}
FileInputStream fis = new FileInputStream(file);//将文件对象直接扔进来往里面写内容

prop.load(fis); //使用Properties中的load()方法,加载六中的数据
fis.close(); //关流
}

}
import java.io.*;
import java.util.*;

/*
定义一个功能,用于记录住程序运行的次数。
如果运行次数满足5次。试用期已到,请注册。

我们就需要一个计数器。
而且要将这个计数器的值持久化存储到硬盘上。
每次这个软件启动,都需要先读取这个配置文件。
并取出这里的数值,进行自增后,在重新存储回去。

*/


class PropertiesTest
{
public static void main(String[] args)throws IOException
{
Properties prop = new Properties();

File file = new File("count.properties");

if(!file.exists())
file.createNewFile();

FileInputStream fis = new FileInputStream(file);

//加载流中的数据。
prop.load(fis);

//获取count键对应的值。
String value = prop.getProperty("count");

int count = 0;
if(value!=null)
{
count = Integer.parseInt(value);
if(count>=5)
{
System.out.println("您好,试用次数已到,给钱!");
return;
}
}
count++;

prop.setProperty("count",count+"");

FileOutputStream fos = new FileOutputStream(file);

prop.store(fos,"");

fos.close();//一般的,后开的流资源先关闭
fis.close();

}
}

 

java培训、android培训期待与您交流!
原创粉丝点击