赞
踩
1. File(文件特征与管理):用于文件或者目录的描述信息,例如生成新目录,修改文件名,删除文件,判断文件所在路径等。
2. InputStream(二进制格式操作):***抽象类***,基于字节的输入操作,是所有输入流的父类。定义了所有输入流都具有的共同特征。
3. OutputStream(二进制格式操作):***抽象类***。基于字节的输出操作。是所有输出流的父类。定义了所有输出流都具有的共同特征。
4.Reader(文件格式操作):***抽象类***,基于字符的输入操作。
5. Writer(文件格式操作):***抽象类***,基于字符的输出操作。
6. RandomAccessFile(随机文件操作):一个独立的类,直接继承至Object.它的功能丰富,可以从文件的任意位置进行存取(输入输出)操作。
/**
* 字节流
*读文件
* */
import java.io.*;
class hello{
public static void main(String[] args) throws IOException {
String fileName="D:"+File.separator+"hello.txt";
File f=new File(fileName);
InputStream in=new FileInputStream(f);
byte[] b=new byte[1024];
int count =0;
int temp=0;
while((temp=in.read())!=(-1)){
b[count++]=(byte)temp;
}
in.close();
System.out.println(new String(b));
}
}
import java.io.DataOutputStream ;
import java.io.File ;
import java.io.FileOutputStream ;
public class DataOutputStreamDemo{
public static void main(String args[]) throws Exception{ // 所有异常抛出
DataOutputStream dos = null ; // 声明数据输出流对象
File f = new File("d:" + File.separator + "order.txt") ; // 文件的保存路径
dos = new DataOutputStream(new FileOutputStream(f)) ; // 实例化数据输出流对象
String names[] = {"衬衣","手套","围巾"} ; // 商品名称
float prices[] = {98.3f,30.3f,50.5f} ; // 商品价格
int nums[] = {3,2,1} ; // 商品数量
for(int i=0;i<names.length;i++){ // 循环输出
dos.writeChars(names[i]) ; // 写入字符串
dos.writeChar('\t') ; // 写入分隔符
dos.writeFloat(prices[i]) ; // 写入价格
dos.writeChar('\t') ; // 写入分隔符
dos.writeInt(nums[i]) ; // 写入数量
dos.writeChar('\n') ; // 换行
}
dos.close() ; // 关闭输出流
}
};
import java.io.DataInputStream ;
import java.io.File ;
import java.io.FileInputStream ;
public class DataInputStreamDemo{
public static void main(String args[]) throws Exception{ // 所有异常抛出
DataInputStream dis = null ; // 声明数据输入流对象
File f = new File("d:" + File.separator + "order.txt") ; // 文件的保存路径
dis = new DataInputStream(new FileInputStream(f)) ; // 实例化数据输入流对象
String name = null ; // 接收名称
float price = 0.0f ; // 接收价格
int num = 0 ; // 接收数量
char temp[] = null ; // 接收商品名称
int len = 0 ; // 保存读取数据的个数
char c = 0 ; // '\u0000'
try{
for(int i=0;i<3;i++){ //如果是while(true)是会产生EOFException的!!!!
temp = new char[200] ; // 开辟空间
len = 0 ;
while((c=dis.readChar())!='\t'){ // 接收内容
temp[len] = c ;
len ++ ; // 读取长度加1
}
name = new String(temp,0,len) ; // 将字符数组变为String
price = dis.readFloat() ; // 读取价格
dis.readChar() ; // 读取\t
num = dis.readInt() ; // 读取int
dis.readChar() ; // 读取\n
System.out.printf("名称:%s;价格:%5.2f;数量:%d\n",name,price,num) ;
}
}catch(Exception e){e.printStackTrace;} //原作者没有写e.printStackTrace;这句话
dis.close() ;
}
};
经过这个例子会对这个类有所理解,下面这两句话对理解这个类很有帮助:
DataInputStream是数据输入流,可以读取java的基本数据类型。
FileInputStream是从文件系统中,读取的单位只能是字节。
/**
* 回退流操作
* */
public class PushBackInputStreamDemo{
public static void main(String[] args) throwsIOException{
public static void main(String[] args) throws Exception
{
String s="123456789";
byte b[]=s.getBytes();
BufferedInputStream bis=new BufferedInputStream(new ByteArrayInputStream(b));
PushbackInputStream pis=new PushbackInputStream(bis);
int tmp=1;
int i=0;
while((tmp=pis.read())!=-1)
{
if(tmp=='3') //监听
{
pis.unread('n'); //修改
tmp=pis.read(); //修改后的值保存到变量tmp
}
System.out.print((char)tmp);
i++;
}
pis.close();
}
}
}
ByteArrayInputStream基本的介质流之一,它从Byte数组中读取数据。
FIleInputStream也是基本的介质流之一,它从文件中读取数据。
PushBackInputStream的作用:监听流中的数据,如果监听到自己感兴趣的数据可以对其进行改写。
public class DataInputStreamDemo {
private static final String FILENAME="E:\\迅雷下载\\越狱.Prison.Break.S05E06.中英字幕.HDTVrip.720P.mp4";
public static void main(String[] args) throws IOException {
long l1 = readByBufferedInputStream();
long l2 = readByInputStream();
System.out.println("通过BufferedInputStream读取用时:"+l1+";通过InputStream读取用时:"+l2);
// System.out.println("通过BufferedInputStream读取用时:"+l1);
}
public static long readByInputStream() throws IOException {
InputStream in=new FileInputStream(FILENAME);
byte[] b=new byte[8192];
int l=0;
long start=System.currentTimeMillis();
while(in.read(b)!=-1){
}
long end=System.currentTimeMillis();
return end-start;
}
public static long readByBufferedInputStream() throws IOException {
BufferedInputStream in=new BufferedInputStream(new FileInputStream(FILENAME));
byte[] b=new byte[8192];
int l=0;
long start=System.currentTimeMillis();
while(in.read(b)!=-1){
}
long end=System.currentTimeMillis();
return end-start;
}
}
上面的程序我们再多测试几种情况:
两个new byte[8192]的情况下:
通过BufferedInputStream读取用时:325;通过InputStream读取用时:320
两个new byte[4096]的情况下:
通过BufferedInputStream读取用时:356;通过InputStream读取用时:501
两个new byte[1024]的情况下:
通过BufferedInputStream读取用时:355;通过InputStream读取用时:1467
两个new byte[512]的情况下:
通过BufferedInputStream读取用时:370;通过InputStream读取用时:2847
两个new byte[256]的情况下:
通过BufferedInputStream读取用时:374;通过InputStream读取用时:5457
我们发现BufferedInputStream的优势显现出来了,快了10多倍。
其实明确一点:读取数据的快慢和程序访问磁盘的次数(IO操作)是有极大关系的,可以说是主要影响因素。
BufferedInputStream自身维护了一个默认8192字节(8K)的缓冲区,这个缓冲区有什么用呢?
如果一份文件8M,那么程序访问了8M/8=1000次
new byte[8192],new byte[4096],new byte[1024],new byte[512],new byte[256]是程序自己维护的数组,数来存储缓冲区数据,8K缓冲区仍然没有改变,那么访问磁盘次数没变,所以时间大体上是相同的。
也可以说是此例子中的BufferedInputStream类自身维护了一个8K缓冲区,程序员又为他提供了一个new Byte数组来记录缓冲区中的数据。8K的缓冲区不变,读取时间不会有很大变化。
FileInputStream没有缓冲区,我们是通过创建一个New Byte数组来模拟缓冲区。
new byte[8192],new byte[4096],new byte[1024],new byte[512],new byte[256]不同的byte数组会使得访问磁盘次数产生很大变化,进而影响读取时间,所以时间变化大而且细心的会发现呈现指数变化。
两个类都有8K缓冲区:
BufferedInputStream类自身维护的8K缓冲区
我们为FileInputStream模拟的8Kbyte数组
所以他们访问磁盘的次数相同,但是BufferedInputStream不是单纯的维护一个数组,还要维护数组中其他“东西”(我也不想弄清楚有啥)所以他的操作慢一些。
关键是弄明白两个new byte的作用!
BufferedInputStream中的new byte[]是存储缓冲区中的数据,属于内存操作,速度快,对读取时间影响小
FileInputStream中的new byte[]起到的是缓冲区的作用,属于IO操作,速度慢,对读取时间影响大。
FileInputStream fis = new FileInputStream("c:\\0.mp3");
FileOutputStream fos = new FileOutputStream("c:\\1.mp3");
byte[] buf=new byte[1024];
int len=0;
while((len=fis.read())!=-1)
{
fos.write(buf,0,len);
}
fos.close();
fis.close();
FileInputStream fis = new FileInputStream("c:\\0.mp3");
BufferedInputStream bis=new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream("c:\\1.mp3");
BufferedOutputStream bos=new BufferedOutputStream(fos);
byte[] buf=new byte[1024]; //这句话对效率的提升也有很大帮助,不光需要BufferedInputStream、BufferedOutputStream的内部缓冲区来提升效率。
int len=0;
while((len=fis.read())!=-1)
{
fos.write(buf,0,len);
}
fos.close();
fis.close();
/**
* 使用内存操作流将一个大写字母转化为小写字母
* */
import java.io.*;
class hello{
public static void main(String[] args) throws IOException {
String str="ROLLENHOLT";
ByteArrayInputStream input=new ByteArrayInputStream(str.getBytes());
ByteArrayOutputStream output=new ByteArrayOutputStream();
int temp=0;
while((temp=input.read())!=-1){
char ch=(char)temp;
output.write(Character.toLowerCase(ch));
}
String outStr=output.toString();
input.close();
output.close();
System.out.println(outStr);
}
}
public class DataInputStreamDemo {
//private static final String FILENAME="E:\\迅雷下载\\越狱.Prison.Break.S05E06.中英字幕.HDTVrip.720P.mp4";
public static void main(String[] args) throws IOException {
PipedInputStream input=new PipedInputStream();
PipedOutputStream output=new PipedOutputStream();
input.connect(output);
new Thread(new Input(input)).start();
new Thread(new Output(output)).start();
}
}
class Input implements Runnable
{
private PipedInputStream in;
Input(PipedInputStream in)
{
this.in=in;
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
byte[] b=new byte[1024];
int len=in.read(b);
String s=new String(b,0,len);
System.out.println("s="+s);
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class Output implements Runnable
{
private PipedOutputStream out;
Output(PipedOutputStream out)
{
this.out=out;
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
//Thread.sleep(5000);
out.write("hi.管道来了".getBytes());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
控制台输出:
s=hi.管道来了
此流不建议用于单线程,可能会引起死锁。因为read方法是阻塞式方法,在单线程中读取不到数据会一直等待,write方法执行不到。
public class Test
{
private static final int BUFFER_SIZE=1024;
public static void main()
{
FileReader fr=null;
FileWriter fw=null;
try
{
fr=new FileReader("1.txt");
fw=new FileWriter("2.txt");
//创建一个临时容器,用于缓存读取到的字符
char[] buf=new char[BUFFER_SIZE];//这就是缓冲区
//定义一个变量记录读取到的字符数,(其实就是往数组里装的字符个数)
int len=0;
while((len=fr.read(buf))!=-1)
{
fw.write(buf,0,len);
}
}catch(Exception e)
{
throw new RuntimeException("读写失败");
}finally
{
if(fw!=null)
try
{
fw.close();
}catch(Exception)
{
e.printStackTrace();
}
if(fr!=null)
try
{
fr.close();
}catch(Exception)
{
e.printStackTrace();
}
}
}
}
public class test
{
public static void main()
{
FileReader fr=new FileReader("1.txt");
BufferedReader bufr=new BufferedReader(fr);
FileWriter fw=new FileWriter("2.txt");
BufferedWriter bufw=new BufferedWriter(fw);
String line=null;
while((line=bufr.readLine())!=null)
{
bufw.write(line);
bufw.newLine();
bufw.flush();
}
bufr.close();
bufw.close();
}
}
public class test
{
public static void mian(String[] args)throws IOException
{
//控制台输入
InputStream in=System.in;
//通过转换流转换成字符数据,方便操作
InputStreamReader isr=new InputStreamReader(in);
//加入缓冲更高效
BufferedReader bufr=new BufferedReader(isr);
OutputStream out=System.out;
OutputSteamWriter osw=new OutputStream(out);
BufferedWriter bufw=new BufferedWriter(osw);
String line=null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
bufw.write(line.toupperCase());
bufw.newLine();
bufw.flush();
}
}
}
不使用转换流也可以完成上述功能,本例子就是为了加深转换流的印象才用的转换流。
当需要明确码表的时候
public static void main(String[] args) throws IOException {
//在IO流中,如果想指定编码读写数据,只能使用转换流。
//采用指定编码从文本文件中读取内容
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("C:\\a.txt"), "UTF-8"));
String line = null;
while ((line=br.readLine())!=null) {
System.out.println(line);
}
br.close();
}
public static void main(String[] args) throws IOException {
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("C:\\a.txt"), "UTF-8"));
bw.write("I am 。。");
bw.close();
}
想要知道开发时用到哪个对象。只要通过四个明确即可。
1、明确源和目的
源:InputStream Reader
目的:OutputStream Writer
2、明确数据是否是纯文本。
源:是纯文本:Reader
否:InputStream
目的:是纯文本:Writer
否:OutputStream
3、明确具体的设备:
源设备:
硬盘:File
键盘:System.in
内存:数组
网络:Socket流
目的设备:
硬盘:File
键盘:System.in
内存:数组
网络:Socket流
4、是否需要额外功能
1、是否需要高效(缓冲区)
是就加上buffer
2、转换
1、明确源和目的:
源:InputStream Reader
目的:OutputStream Writer
2、是否是纯文本?
是
源:Reader
目的:Writer
3、明确具体设备
源:
硬盘:File
目的;
硬盘:File
FileReader fr=new FileReader(“1.txt”);
FileWriter fw=new FileWriter(“2.txt”);
4、需要额外功能吗?
需要:高效
BufferedReader bufr=new BufferedReader(new FileReader(“1.txt”));
BufferedWriter bufw=new BufferedWriter(new FileWriter(“2.txt”));
1、明确源和目的。
源:InputStream Reader
目的:OutputStream writer
2、是否是纯文本呢?
是
源:Reader
目的:Writer
3、明确具体设备
源:
键盘:System.in
目的;
硬盘:File
InputStream in=System.in;
FileWriter fw=new FileWriter(“1.txt”);
4、是否需要额外功能?
是:需要转换
InputStreamWriter isw=new InputStreamWriter(System.in);
FileWriter fw=new FileWriter(“1.txt”);
还需要功能吗?需要高效
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in))
BufferedWriter bufw=new BufferedWriter(new FileWriter(“1.txt”));
1、明确源和目的。
源:InputStream Reader
目的:OutputStream writer
2、是否是纯文本呢?
是
源:Reader
目的:Writer
3、明确具体设备
源:
硬盘:File
目的;
显示器:System.out
FileReader fr=new FileReaderr(“1.txt”);
OutputStream os=System.out;
4、需要额外功能吗?
需要,转换
FileReader fr=new FileReader(“1.txt”);
OutputStreamWriter osw=new OutputStreamWriter(System.out);
需要,高效
BufferedReader bufr=new BufferedReader(new FileReader(“1.txt”));
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));
1、明确源和目的。
源:InputStream Reader
目的:OutputStream writer
2、是否是纯文本呢?
是
源:Reader
目的:Writer
3、明确具体设备
源:
键盘:System.in
目的;
显示器:System.out
InputStream in=System.in;
OutputStream out=System.out;
4、明确额外功能
需要转换:
InputStreamReader isr=new InputStreamReader(System.in);
OutputStreamWriter osw=new OutputStreamWriter(System.out);
为了将其高效。
BufferedReader bufr=new BufferedReader(new InputStreamReaer(System.in));
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));
1、明确源和目的。
源:无
目的:OutputStream writer
2、是否是纯文本呢?
是
源:无
目的:Writer
3、明确具体设备
源:
无
目的;
硬盘:File
FileWriter fw=new FileWriter(“1.txt”);
4、需要额外功能吗?
需要转换
注意:既然需求明确了制定编码表的动作那就不可以使用FileWriter,因为FileWriter内部是使用默认的本地码表。只能使用其父类OutputStreamWriter,OutputStreamWriter接受一个字节输出流对象,既然是操作文件,那么应该是FileOutputStream
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream(“1.txt”),charset);
需要高效吗?
需要
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(“1.txt”),charset))
还需要详解一下
Java的IO模型设计非常优秀,它使用Decorator(装饰者)模式,按功能划分Stream,您可以动态装配这些Stream,以便获得您需要的功能。
例如,您需要一个具有缓冲的文件输入流,则应当组合使用FileInputStream和BufferedInputStream。
参考资料:
http://blog.csdn.net/tanqian351/article/details/51209438
https://www.2cto.com/kf/201312/262036.html
http://blog.csdn.net/jiangwei0910410003/article/details/22376895
http://blog.csdn.net/u013087513/article/details/52148934
http://bbs.csdn.net/topics/390517474/
http://blog.csdn.net/u013905744/article/details/51924258
毕向东Java讲义 PDF版
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。