——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
黑马程序员–Java之IO(输入输出)(上)03
IO流有很多种,按照操作数据的不同,可以分为字节流和字符流,按照数据传输方向的不同又可分为输入流和输出流,程序从输入流中读取数据,向输出流中定稿数据。在IO包中,字节流的输入输出流分别用java.io.InputStream和java.io.OutputStream表示,字符流的输入输出流分别用java.io.Reader和java.io.Writer表示。
一、字节流的输入输出
字节流是程序中最常用的流,用于操作图片等非文本文件。
FileOutputStream fos=new FileOutputStream("fos.txt");
fos.write("abcde".getBytes()); //参数是 byte数组,不支持字符串 String 变字符数组
fos.close();
FileInputStream fis=new FileInputStream("fos.txt");
int ch=0
while((ch=fis.read())!=-1){ //读取文件,读一个输出一个
System.out.println((char)ch);
}
byte[] buf=new byte[1024];//创建字节数组
int len=0;
while((len=fis.read(buf))!=-1){ //把读取的数据保存到数组中
System.out.println(new String(buf,0,len));//字节数组变String
}
// int num=fis.available(); //读取文本字节的个数,包括换行符
byte[]buf=new byte[fis.available()];//数据过大会造成溢出
fis.read(buf); //不需要循环
System.out.println(new String(buf)); //字符数组变成字符串
字节读取流与图片关联,通过写入流创建一个新的图片文件以存储图片,通过循环读取完成数据的读取。
class CopyPic{
public static void main(String[] args){
FileOutStream fos =null;
FileInputStream fis=null;
try{
fos=new FileOutputStream("e:\\2.bmp");
fis=new FileInputStream("e:\\1.bmp");
byte[] buf=new byte[1024]
int len=0;
while(( len=fil.read(buf))!=-1){
fos.write(buf,0,len);
}
}catch(IOException e){
throw new RuntimeExcepion("复制文件失败”);
}
finally{
try{
if(fis!=null){
fis.close();
}
}catch(IOException e){
throw new RuntimeExcepion("流关闭失败”);
}
try{
if(fos!=null)
fos.close();
}catch(IOException e){
throw new RuntimeExcepion("流关闭失败”);
}
}
}
}
通过字节流的缓冲区技术完成复制媒体文件
import java.IO.*;
class CopyMp3{
public static void main(String[] args){
long start=System.currentTimeMillis();
copy();
long end=System.currentTimeMillis();
System.out.println((end-start)+"毫秒");
}
public static void copy throw IOException{
BufferedInputStream bufis=new BufferedInputStream(new FileInputStream("e:\1.mp3");
BufferedOutputStream bufos=new BufferedOutputStream(new FileOutputStream("e:\2.mp3");
int by=0;
while((by=bufis.read())!=-1){
bufos.write(by);
}
bufos.close();
bufis.close();
}
}
二、字符流的输入和输出
在硬盘上创建一个文件,并写入数据
FileWriter 是一个专门操作文件的Writer子类对象是OutputStreamWriter的子类(Writer类的子类)。
class FileWriterDemo{
public static void main(String[] args) throws IOException {
//常见FileWriter对象并被初始化明确被操作的文件,
//如果文件不存在则被创建,文件存在则被覆盖,
FileWrite fw=new FileWriter("abc.txt"); //存在需要处理的异常
fw.write("gogogo"); //fw调用的方法都会抛出异常
fw.flush();
// 将数据写入流,写入文件需要刷新流的缓冲,调用一次刷新一次
fw.close(); // 刷新流并关闭流资源
}
}
程序中write(); flush(); close() 都可能抛出IO异常,该如何处理?
class FileWriteDemo{
public static void main(String[] args){
FileWriter fw; //FileWriter对象变量应该在try外面声明,
//在里面如果发生异常则使finanlly{}中的close无法调用
try{
fw=new FileWriter("mybook.txt");
fw.write("abcde"); //字符流的输出
}catch(IOEception e){
System.out.println(e.toString()):
}finally{
try{ //单独处理该异常是因为前面报异常就无法关闭流资源
if(fw!=null) //File对象可能创建失败,fw为null,不能调用close();
fw.close();
}catch(IOEception){
System.out.println(e.toString());
}
}
}
}
如何在一个已经存在的文件续写数据
new FileWriter(String filename,boolean append) //append值为true时将数据写入文件的末尾处,
FileWriter fw=new FileWriter(“abc.txt”,true);
fw.write(“abcdef”);
fw.close();
在硬盘上打开一个文件,并读取数据,FileReader是读取文件数据的reader的子类对象
class FilReaderDemo{
public static void main(String[] args) throws IOException{
FileReader fr =new FileReader("abc.txt");
//FileNotFoundException异常
/*int ch1=fr.read();
//每次读一个字符,并自动往下读,直到读到文件末尾返回-1
System.out.println("ch1="(char)ch1);
int ch2=fr.read();
System.out.println("ch2="(char)ch2);*/
/* while(true){ //循环读取直至文件末尾
int ch=fr.read();
if(ch==-1)
break;
System.out.println("ch="(char)ch); */
int ch=0;
while((ch==fr.read())!=-1){
System.out.println("ch="(char)ch);
}
fr.close();
}
}
}
第二种方式,通过字符数组进行读取。
//FileReader fr=new FileReader("abc.txt");
//char[] buf=new char[];
//int num=fr.read(buf); // 将字符读入数组,并返回读到的数目,
int num=0;
while((num=fr.read(buf))!=-1){ //结尾没有数据返回-1
System.out.println(new String(buf,0,num);
}
将C盘中的一个文件复制到D盘,原理:定义读取流与C盘相关联,在D盘创建一个新的文件,通过不断地读写完成数据的存储
class CopyText{
public static void main(String[] args){
}
public static void copy1()throws IOException{
//读一个字符就写一个
FileWrite fw=new FileWriter("d:\\abc.txt");
FileReader fr=new FileReader("abc.java");
//将输入流与输出流分别与文件关联
int ch=0
while((ch=fr.read())!=-1){
fw.write(ch);
}
fw.close();
fr.close();
}
public statci void copy2(){ //读一个字符串,写一个字符串
FileWriter fw=null; //声明变量与创建对象分开,
FileReader fr=null;
try{
fw=new FileWriter();
fr=new FileReader();
char[] buf=new char[1024];
int len=0;
while((len=fr.read(buf)))!=-1){
fw.write(buf,0,len);
}
}catch(IOException e){
throw new RuntimeException ("failed");
}
finally{
if(fr!=null){
try{
fr.close();
}catch(IOException e){
throw new RuntimeException ("failed");
}
if(fw!=null){
try{
fw.close();
}catch(IOException e){
throw new RuntimeException ("failed");
}
}
}
}
}
}
字符流中的缓冲区技术: 缓冲区用以提高对数据读写的效率。对应类 BufferedWriter、BufferedReader,缓冲区需要结合流来使用,并增强流的功能,创建缓冲区之前,必须先有流对象,不能再创建时有空参数。
class BufferedWriterDemo{
public static void main(Sting[] args)throws IOExcetion{
FileWriter fw=new FileWriter("abc.txt);
BufferedWriter bufw=new BufferedWriter(fw);
//将流对象作为参数传递给缓冲区
bufw.write("abcde");
bufw.newline();
//跨平台的换行符,只在Buffered类中有newLine()方法
bufw.flush();
bufw.close();
}
}
字符读取缓冲区提供了一个一次读一行的方法,readLine();
class BufferedReaderDemo{
public static void main(String[] args){
FileReader fr =new FileReader("buf.txt");
BufferedReader bufr=new BufferedReader(fr);
String line=null;
//返回包含该行内容的字符串,不含任何终止符,如果已达文件末尾,返回Null
// String s1=bufr.readLine();
//System.out.println(s1);
while((line=bufr.readLine())!=null){
System.out.println(line)
}
bufr.close();
}
}
LineNumeberReader (BufferedReader的子类):可以跟踪行号的缓冲字符输入流。方法如下:
getLineNumber() //获取行号
setLineNunber() //设置行号
readLine ()//按行读取
class LineNumberReaderDemo{
public static void main(String[] args) throws IOException{
LineNumber lnr = new LineNumber(new FileReader("c:\\java");
String line = null;
lnr.setLineNumber(100);
while((line=lnr.readLine())!=null){
System.out.println(lnr.getLineNumber()+line");
}
lnr.close();
}
}