Java输出流的坑_java输入/输出流的基本知识

通过流可以读写文件,流是一组有序列的数据序列,以先进先出方式发送信息的通道。

输入/输出流抽象类有两种:InputStream/OutputStream字节输入流和Reader/Writer字符输入流。

一、字节流

1.InputStream类

d395bc6d31724815d4a294ad75f5068d.png

int read():从输入流中读取下一个字节,并返回该字节对应的整型数字 0-255。

int read(byte[ ] b):从输入流中读取多个字节,并将字节存放到数组b[ ]中,返回读到的字节个数,即数组长度。

int read(byte[ ] b ,int off ,int len):从输入流中读取多个字节,并将字节存放到数组b[ ]中,从数组的off位置处开始存放,len是读到的字节个数。

2.OutputStream类

930d0f9fb397cc7a112af473ad634c9a.png

字节流输入步骤:

1.引用相关类;

2.创建FileInputStream类对象;

3.读取文本文件;

4.关闭流。

字节流输出步骤:

1.引用相关类;

2.创建FileOutputStream类对象;

3.写入文本文件;

4.关闭流。

案例:

packagecom.yh.filestring;import java.io.*;public classFileTest2 {public static voidmain(String[] args) {//创建目录

File dir = new File("d:/eclipseWJ/HelloWorld/FileTest2");

dir.mkdirs();//创建文件

File file = new File("d:/eclipseWJ/HelloWorld/FileTest2/test2.txt");

FileOutputStream fos= null;

FileInputStream fis= null;try{

if(!file.exists())

file.createNewFile();

fos= new FileOutputStream(file,true); // 在文件原有的内容上追加

fos = new FileOutputStream(file); // 直接覆盖文件原有的内容

String str= "学习Java!";byte[] words =str.getBytes();

fos.write(words,0, words.length);//创建输入流对象

fis = newFileInputStream(file);intdata;while ((data = fis.read()) != -1) {

System.out.print((char) data);

}

}catch(FileNotFoundException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(IOException e) {//TODO Auto-generated catch block

e.printStackTrace();

}finally{//关闭输入流

try{

fos.close();

fis.close();

}catch(IOException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

案例:将file1中的内容复制到file2

packagecom.yh.filestring;import java.io.*;public classFileCopy {public static voidmain(String[] args) {

File dir= new File("D:/eclipseWJ/HelloWorld/filecopy");

File file1= new File("D:/eclipseWJ/HelloWorld/filecopy/file1.txt");

File file2= new File("d:/eclipseWJ/HelloWorld/filecopy/file2.txt");

dir.mkdirs();

FileInputStream fis= null;

FileOutputStream fos= null;try{

if(!file1.exists())

file1.createNewFile();

if(!file2.exists())

file2.createNewFile();

fos= newFileOutputStream(file1);

String str= "HelloWorld";byte[] words =str.getBytes();

fos.write(words,0, str.length());

fos.close();

fis= newFileInputStream(file1);

fos= new FileOutputStream(file2, true);intlen;byte[] word = new byte[1024];while ((len = fis.read(word)) != -1) { // 读取到的字节存到数组word[]中,追加存储

fos.write(word,0,len);

}

fis.close();

fis= newFileInputStream(file2);intdata;while ((data = fis.read()) != -1) {

System.out.print((char)data);

}

}catch(IOException e) {//TODO Auto-generated catch block

e.printStackTrace();

}finally{try{

fis.close();

fos.close();

}catch(IOException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

二、字符流

1.Reader类

0550b5cdc8543fc2dde4baa4346de6ca.png

Reader类常用方法:

int read():从输入流中读取下一个字符,并返回该字符对应的整型数字 0-65535。

int read(char[ ] c):从输入流中读取多个字符,并将字符存放到数组b[ ]中,返回读到的字符个数,即数组长度。

int read(char[ ] c ,int off ,int len):从输入流中读取多个字符,并将字符存放到数组b[ ]中,从数组的off位置处开始存放,len是读到的字符个数。

子类InputStreamReader常用构造方法:

InputStreamReader(InputStream in):参数是一个字节流对象,将一个字节流包装成字符流,读取内容按本地平台默认编码。

InputStreamReader(InputStream in ,String charserName):参数是一个字节流对象和字符集编码,先将字节流包装成字符流,然后再按照这个字符集编码来读取到内容。

步骤:

1.创建FileInputStream类对象(字节流);

2.创建InputStreamReader类对象,并将FileInputStream类对象和字符集编码名字作为构造函数的参数(字符流);

3.创建BufferedReader类对象,并将InputStreamReader类对象作为构造函数的参数(字符流);

4.读取文本。

代码示例(较为综合):

packagecom.yh.filestring;import java.io.*;public classInputStreamReaderDemo {public static voidmain(String[] args) {//TODO Auto-generated method stub

File file = new File("D:\\eclipseWJ\\HelloWorld\\Chapter\\File3.txt");

InputStream is= null;

Reader isr= null;

BufferedReader br= null;try{

is= newFileInputStream(file);

isr= new InputStreamReader(is,"UTF-8");

br= newBufferedReader(isr);

StringBuffer bf= newStringBuffer();

String line= null;if((line = br.readLine())!=null) {

bf.append(line);

}

System.out.println(bf);

}catch(FileNotFoundException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(IOException e) {//TODO Auto-generated catch block

e.printStackTrace();

}finally{try{

br.close();

isr.close();

}catch(IOException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

文本文件读取类FileReader是InputStreamReader的子类:

构造方法:

FileReader(File file)

FileReader(String pathName)

FileReader只能按照本地平台的字符编码来读,不能通过用户特定的字符集编码来读。

本地平台字符集编码获得:String encoding = System.getProperty("file.encoding");

使用FileReader类读取文本步骤:

1.引用相关类;

2.创建FileReader类对象;

3.读取文本文件;

4.关闭流。

代码示例:

packagecom.yh.filestring;import java.io.*;public classFileReaderDemo {public static voidmain(String[] args) {

FileReader filereader;try{

filereader= new FileReader("d:/eclipseWJ/HelloWorld/FileTest2/test2.txt");

StringBuffer sbf= newStringBuffer();char[] words = new char[1024];while(filereader.read(words)!=-1) { //while只执行一次

sbf.append(words);

}

System.out.println(sbf);

}catch(FileNotFoundException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(IOException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

}

}

BufferReader类:带有缓冲区的字符输入流

代码示例:

packagecom.yh.filestring;import java.io.*;public classFileTestBuffer {public static voidmain(String[] args) {

BufferedReader reader= null;try{//创建目录

File dir = new File("Chapter");

dir.mkdirs();//创建文件

File f = new File("D:\\eclipseWJ\\HelloWorld\\Chapter\\File1.txt");

f.createNewFile();//写入文本

FileWriter writer = newFileWriter(f); // 覆盖重写

FileWriter writer = new FileWriter(f, true); // 追加

BufferedWriter bufferedwriter= newBufferedWriter(writer);

bufferedwriter.write("你好");

bufferedwriter.flush(); //将缓冲区的内容全部写入文本

bufferedwriter.close();//输出目录中的文件

if(dir.isDirectory()) {

String[] fileContents=dir.list();for(String i : fileContents)

System.out.println(i);

}//读出文件内容

FileReader fileReader = newFileReader(f);

reader= newBufferedReader(fileReader);

String line= null;while ((line = reader.readLine()) != null)

System.out.println(line);

}catch(FileNotFoundException ex) {

ex.printStackTrace();

}catch(IOException ex) {

ex.printStackTrace();

}finally{try{

reader.close();

}catch(IOException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

2.Writer类

参考上述Reader类。

三、读写二进制文件

读取特定图片并完成该图片的复制

代码示例:

packagecom.yh.filestring;import java.io.*;public classFIleImg {public static voidmain(String[] args) {//TODO Auto-generated method stub

FileInputStream fis = null;

DataInputStream dis= null;

FileOutputStream fos= null;

DataOutputStream dos= null;try{

fis= new FileInputStream("D:\\eclipseWJ\\HelloWorld\\fish.jpg");

dis= newDataInputStream(fis);

fos= new FileOutputStream("D:\\eclipseWJ\\HelloWorld\\newfish.jpg");

dos= newDataOutputStream(fos);intdata;while ((data = dis.read()) != -1) {

dos.write(data);

}//dos.flush();

} catch(FileNotFoundException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(IOException e) {//TODO Auto-generated catch block

e.printStackTrace();

}finally{try{

dos.close();

fos.close();

dis.close();

fis.close();

}catch(IOException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

四、序列化和反序列化

五、总结

1.类的继承关系总结:

InputStream类(字节流)—— FileInputStream类 —— DataInputStream类(读取二进制文件)

OutputStream类(字节流)—— FileOutputStream类 —— DataOutputStream类(写入二进制文件)

Reader类(字符流)—— InputStreamReader类(构造函数参数:一个字节流InputStream类对象和字符集编码名字)和BufferedReader类(构造函数参数:一个Reader对象,提供通用的缓冲方式文本读取,readLine读取一个文本行)—— FileReader类(构造函数参数:File类对象或完整路径,无法指定字符集编码)

Writer类(字符流)—— OutputStreamWriter类(构造函数参数:一个字节流OutputStream类对象和字符集编码名字)和BufferedWriter类(构造函数参数:一个Writer对象,提供通用的缓冲方式文本写入)—— FileWriter类(构造函数参数:File类对象或完整路径,无法指定字符集编码)

2.字节和字符的关系:

Java采用unicode来表示字符,java中的一个char是2个字节,一个中文或英文字符的unicode编码都占2个字节,但如果采用其他编码方式,一个字符占用的字节数则各不相同。

在 GB-2312 编码或 GBK 编码中,一个英文字母字符存储需要1个字节,一个汉子字符存储需要2个字节。

在UTF-8编码中,一个英文字母字符存储需要1个字节,一个汉字字符储存需要3到4个字节。

在UTF-16编码中,一个英文字母字符存储需要2个字节,一个汉字字符储存需要3到4个字节(Unicode扩展区的一些汉字存储需要4个字节)。

在UTF-32编码中,世界上任何字符的存储都需要4个字节。

3.flush()方法

在进行文件写入相关操作时,需要调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值