您的位置:首页 > 编程语言 > Java开发

Java基础--IO流之字节流

2015-04-28 11:17 225 查看
凌风博客原创作品。转载请注明出处:http://blog.csdn.net/q549130180/article/details/45333403

字符流:
FileReader

FileWriter

BufferedReader

BufferedWriter

字节流:

inputStream OutputStream

[java] view
plaincopy





import java.io.*;

class FileStream12

{

public static void main(String[] args)

{

readFile_3();

}

public static void readFile_3() throws IOException

{

FileInputStream fis = new FileInputStream("fos.txt");

//数据特别的的时候不宜使用,还是使用readFile_2的方法

//因为数据特别大的时候,会发生内存溢出

byte[] buf = new byte[fis.available()]; //定义一个刚刚好的缓冲区,不用再循环了

fis.read(buf);

System.out.println(new String(buf));

fis.close();

}

public static void readFile_2() throws IOException

{

//使用数组作为缓冲区,整体打印

FileInputStream fis = new FileInputStream("fos.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 readFile_1() throws IOException

{

//读一个字符打印一个字符

FileInputStream fis = new FileInputStream("fos.txt");

int ch = 0;

while ((ch=fis.read())!=-1)

{

System.out.println((char)ch);

}

fis.close();

}

public static void writeFile() throws IOException

{

FileOutputStream fos = new FileOutputStream("fos.txt");

fos.write("abcde".getBytes());

fos.close();

}

}

复制一个图片

思路:

1.用字节读取流对象和图片关联

2.用字节写入流对象创建一个图片文件,用于存储获取到的图片数据

3.通过循环读写,完成数据的存储

4.关闭资源

[java] view
plaincopy





import java.io.*;

class CopyPic13

{

public static void main(String[] args)

{

FileOutputStream fos = null;

FileInputStream fis = null;

try

{

fos = new FileOutputStream("d:\\2.jpeg");

fis = new FileInputStream("d:\\1.jpeg");

byte[] buf = new byte[1024];

int len = 0;

while ((len=fis.read(buf))!=-1)

{

fos.write(buf,0,len);

}

}

catch (IOException e)

{

throw new RuntimeException("复制文件失败");

}

finally

{

try

{

if(fis!=null)

fis.close();

}

catch (IOException e)

{

throw new RuntimeException("读取关闭失败");

}

try

{

if(fos!=null)

fos.close();

}

catch (IOException e)

{

throw new RuntimeException("写入关闭失败");

}

}

}

}

演示mp3的复制,通过缓冲区

BufferedOutputStream

BufferedInputStream

[java] view
plaincopy





import java.io.*;

class CopyMp3_14

{

public static void main(String[] args) throws IOException

{

long start = System.currentTimeMillis();

copy_1();

long end = System.currentTimeMillis();

System.out.println((end-start)+"毫秒");

}

//通过字节流的缓冲区完成复制

public static void copy_1() throws IOException

{

BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("d:\\1.mp3"));

BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("d:\\2.mp3"));

int by = 0;

while ((by=bufis.read())!=-1)

{

bufos.write(by);

}

bufos.close();

bufis.close();

}

}

模拟Buffered

[java] view
plaincopy





import java.io.*;

class MyBufferedInputStream15

{

private InputStream in;

private byte[] buf = new byte[1024*4];

private int pos = 0,count = 0;

MyBufferedInputStream15(InputStream in)

{

this.in = in;

}

//一次读一个字节,从缓冲区(字节数组)获取

public int myRead() throws IOException

{

//通过in对象读取硬盘上数据,并存储buf中

if(count==0)

{

count = in.read(buf);

if(count<0)

return -1;

pos = 0;

byte b = buf[pos];

count--;

pos++;

return b&255;

}else if (count>0)

{

byte b = buf[pos];

count--;

pos++;

return b&0xff;

}

return -1;

}

public void myClose() throws IOException

{

in.close();

}

public static void main(String[] args) throws IOException

{

long start = System.currentTimeMillis();

copy();

long end = System.currentTimeMillis();

System.out.println((end-start)+"毫秒");

}

//通过字节流的缓冲区完成复制

public static void copy() throws IOException

{

MyBufferedInputStream15 bufis = new MyBufferedInputStream15(new FileInputStream("d:\\1.mp3"));

BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("d:\\2.mp3"));

int by = 0;

while ((by=bufis.myRead())!=-1)

{

bufos.write(by);

}

bufos.close();

bufis.myClose();

}

}

/*

byte:-1 ----> int:-1;

00000000 00000000 00000000 11111111 255

11111111 11111111 11111111 11111111

11111111 -->提升了一个int类型,那不还是-1吗? 是-1的原因是因为在8个1前面补的是1导致的。

那么我只要在前面补0,既可以保留原字节数据不变,又可以避免-1的出现。

11111111 11111111 11111111 11111111

&00000000 00000000 00000000 11111111

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

00000000 00000000 00000000 11111111

*/

读取键盘录入

System.out:对应的是标准输出设备,控制台

System.in:对应的标准输入设备,键盘

需求:

通过键盘录入数据

当录入一行数据后,就将该行数据进行打印

如果录入的数据时over,那么停止录入

[java] view
plaincopy





import java.io.*;

class ReadIn16

{

public static void main(String[] args)

{

InputStream in = System.in;

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);

}

}

}

字符流:

FileReader

FileWriter

BufferedReader

BufferedWriter

字节流:

FileInputStream

FileOutputStream

BufferedInputStream

BufferedOutputStream

通过刚才ReadIn16的键盘录入一行数据并打印其大写,发现,其实就是读一行数据的原理

也就是readLine方法

能不能直接使用readLine方法来完成键盘录入的一行操作呢?

readLine方法是字符流BufferedReader类中的方法

而键盘录入的read方法是字节流InputStream的方法。

那么能不能将字节流转换成字符流再使用字符流缓冲区的readLine方法呢?

[java] view
plaincopy





import java.io.*;

class TransStreamDemo17

{

public static void main(String[] args) throws IOException

{

/*

//获取键盘录入对象

InputStream in = System.in;

//将字节流对象转成字符流对象,使用转换流,InputStreamReader

InputStreamReader isr = new InputStreamReader(in);

//为了提高效率,将字符流进行缓冲区技术高效操作,使用BufferedReader

BufferedReader bufr =new BufferedReader(isr);

*/

//键盘录入最常见写法

BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));

/*

//定义一个控制台输出流

OutputStream out = System.out;

//将字符流对象转成字节流对象,使用转换流,

OutputStreamWriter osw = new OutputStreamWriter(out);

//使用字符流缓冲区,已达到高效操作和换行符的跨平台操作

BufferedWriter bufw = new BufferedWriter(osw);

*/

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

String line = null;

while ((line=bufr.readLine())!=null)

{

if("over".equals(line))

break;

//使用OutputStream out = System.out;之后是直接输出到控制台上,而之前的FileOutputStream out = new FileOutputStream("");是输出到文件上

bufw.write(line.toUpperCase()/* +\r\n,如果直接使用\r\n起不到跨平台的作用,只有windows才能识别\r\n*/);

bufw.newLine();//换行

bufw.flush();//刷新

}

bufr.close();

}

}

1.

源:键盘录入

目的:控制台

2.需求:想把键盘录入的数据存储到一个文件中

源:键盘

目的:文件

3.需求:想要将一个文件的数据打印在控制台上

源:文件

目的:控制台

流操作的基本规律:

最痛苦的就是流对象有很多,不知道该用哪一个

通过三个明确来完成

1.明确源和目的

源:输入流。 InputStream Reader

目的:输出流 OutputStream Writer

2.操作的数据是否是纯文本

是:字符流

不是:字节流

3.当体系明确后,在明确要使用哪个具体的对象

通过设备来进行区分:

源设备:内存,硬盘,键盘

目的设备:内存,硬盘,控制台

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

1.需求:将一个文本文件中数据存储到另一个文件中,复制文件

源:因为是源,所以使用读取流。 InputStream Reader

是不是操作文本文件。

是!这时就可以选择Reader

这样体系就明确了。

接下来明确要使用该体系中的那个对象

明确设备:硬盘,上一个文件。

Reader体系中可以操作文件的对象时 FileReader

是否需要提高效率:是!,加入Reader体系中缓冲区 BufferedReader

FileReader fr = new FileReader("a.txt");

BufferedReader bufr = new BufferedReader(fr);

目的:OutputStream Writer

是否是纯文本。

是!Writer

设备:硬盘上一个文本

Writer体系中可以操作文件的对象FileWriter

是否需要提高效率:是!。加入Writer体系中缓冲区 BufferedWriter

FileWriter fw - new FileWriter("b.txt");

BufferedWriter bufw = new BufferedWriter(fw);

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

2.需求:将键盘录入的数据保存到一个文件中

这个需求中有源和目的都存在

那么分别分析

源: InputStream Reader

是不是纯文本?是! Reader

设备:键盘,对应的对象时System.in

不是选择Reader吗?System.in对应的不是字节流吗?

为了操作键盘的文本数据方便,转成字符流按照字符串操作是最方便的。

所以既然明确了Reader,那么就将System.in转换成Reader

用了Reader体系中的转换流,InputStreamReader

InputStreamReader isr = new InputStreamReader(System.in);

需要提高效率吗?需要! BufferedReader

BufferedReader bufr = new BufferedReader(isr);

目的:OutputStream Writer

是不是纯文本文件?是!Writer

设备:硬盘,一个文件,使用FileWriter

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

需要提高效率吗?需要

BufferedWriter bufw = new BufferedWriter(fw);

***************************

扩展一下,想要把录入的数据按照指定的编码表(utf-8),将数据存储到文件中

目的:OutputStream Writer

是不是纯文本文件?是!Writer

设备:硬盘,一个文件,使用FileWriter

但是FileWriter是使用的默认编码表。GBK

但是存储时,需要加入指定编码表utf-8,而指定的编码表只有转换流可以指定

所以要使用的对象是OutputStreamWriter

而该转化流对象要接收一个字节输出流,而且还可以操作的文件的字节输出流,FileOutputStream

OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d.txt"),"UTF-8");

需要高效吗?需要

BufferedWriter bufw = new BufferedWriter(osw);

所以,记住,转换流什么时候使用。字符和字节之间的桥梁,通常,涉及到字符编码转换时。

需要用到转换流

[java] view
plaincopy





import java.io.*;

class TransStreamDemo17_2

{

public static void main(String[] args) throws IOException

{

//改变标准输入输出设备(不常用),两个同时使用就是复制

System.setIn(new FileInputStream("PersonDemo.java"));//改变输入设备为文件

System.setOut(new PrintStream("zzz.txt"));//改变输出设备为文件

//键盘录入最常见写法

BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));

BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("out.txt"),"UTF-8"));//指定编码表的实现

/*

BufferedReader bufr = new BufferedReader(new InputStreamReader(new FileInputStream("ReadIn16.java")));

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()/* +\r\n,如果直接使用\r\n起不到跨平台的作用,只有windows才能识别\r\n*/);

bufw.newLine();//换行

bufw.flush();//刷新

}

bufr.close();

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: