第十章 输入和输出流
名称 | 流 |
---|---|
文件字节输入流 | FileInputStream |
文件字节输出流 | FileOutputStream |
文件字符输入流 | FileReader |
文件字符输出流 | FileWriter |
缓冲输入流 | BufferedReader |
缓冲输出流 | BufferedWriter |
随机流 | RandomAccessFile |
字节数组输入流 | ByteArrayInputStream |
字节数组输出流 | ByteArrayOutputStream |
字符数组输入流 | CharArrayReader |
字符数组输出流 | CharArrayWriter |
数据输入流 | DataInputStream |
数据输出流 | DataOutputStream |
对象输入流 | ObjectInputStream |
对象输出流 | ObjectOutputStream |
10.0 杂
10.1 File类
- 注意
- File 类是一个获取文件属性的类,不能进行读取内容。
- 在创建文件的时候避免使用绝对路径,因为在不同电脑对应的绝对路径是不同的。
- 创建一个File类的对象的方法(自己找帮助文档)
- 例子
package tom.cat; import java.io.*; public class Example10_1 { public static void main(String args[]) { //用相对路径创建一个文件f(相对路径是程序运行时的路径) File f = new File("tom\\cat","Example10_1.java"); //下边就是运用File类里边的方法 System.out.println(f.getName()+"是可读的吗:\n"+f.canRead()); System.out.println(f.getName()+"的长度:\n"+f.length()); System.out.println(f.getName()+"的绝对路径:\n"+f.getAbsolutePath()); //如果file不存在就创建一个空文件 File file = new File("new.txt"); if(!file.exists()) { try { //如果问题存在就创建一个文件夹 file.createNewFile(); System.out.println ("在当前目录(运行程序的目录)下创建了新文件:\n"+file.getName()); } catch(IOException exp){} } } }
10.1.2 目录
- 创建目录的方法
pubilc boolean mkdir()
创建成功返回true,创建失败返回false
- 列出目录中的文件
- 筛选出指定文件
- 方法:
public String[] list(FilenameFilter obj)
该方法用字符串的方式返还目录下指定文件 - 用法
- 继承FilenameFilter类,写一个方法定义accept中的name,然后再重写一下accept方法。
- 方法:
- 筛选出指定文件
package A;
import java.io.File;
public class Example10_2 {
public static void main(String args[]) {
//创建一个File类对象javaDir,文件名称是一个不存在的java文件
File javaDir = new File("java");
System.out.println(javaDir.isDirectory());
/*
* 注意建立文件夹时,文件夹的名称是文件的名称
* 文件夹存在时不能建立文件夹,返回值是false
* File文件是文本文件时不能改成文件夹,返回值是false
*/
boolean boo = javaDir.mkdir();
if(boo) {
System.out.println("新建子目录 "+javaDir.getName());
}
//以dirFile为当前目录依次列出该文件下的目录
File dirFile = new File(".");//点的意思就是当前目录
System.out.println("全部文件(包括文件夹):");
String fileName[] = dirFile.list();
if(fileName == null){
System.out.println("没有文件");
}
else {
for(String name:fileName) {
System.out.println(name);
}
}
//以dirFile为当前目录依次累出java文件
FileAccept fileAccept = new FileAccept();
fileAccept.setExtendName("java");
System.out.println("仅仅列出java源文件:");
File file[] = dirFile.listFiles(fileAccept);
if(file == null){
System.out.println("没有java源文件");
}
else {
for(File f:file) {
System.out.println(f.getName());
}
}
}
}
package A;
import java.io.FilenameFilter;
import java.io.File;
//这个类继承了FilenameFilter类(主要是想用其中的accept方法)
public class FileAccept implements FilenameFilter {
//创建一个私有的变量
private String extendName;
/*其中作者新加了一个setExtendName方法方便用于设定后缀
*另外重写了accept方法,使其返还值是以extendName结尾的文件(之中还用到了String类中的方法)
*/
public void setExtendName(String s) {
//列出后缀为.java的文件
extendName="."+s;
}
public boolean accept(File dir,String name) { //重写接口中的方法
return name.endsWith(extendName);
}
}
10.1.3 文件的创建与删除
注意:file.delete();命令删除文件夹时文件夹为空时才能删除
10.1.4 运行可执行文件
注意:在使用运行文件的时候需要try-catch
10.2 文件字节输入流
- 杂
- 输入是指源(文件)向程序输入
- 注意
- 使用try-catch的原因
- 由于创建输入流的所需要的源可能不存在需要抛出异常
- 输入流中的语句可能会产生异常
- 使用try-catch的原因
- 使用输入流需要的几个步骤
- 设定输入流的源
File f = new File("aaa");
- 创建指向源的输入流
FileInputStream in = new FileInputStream(f);
- 让输入流读取源中的数据
int a = in.read();
- 关闭
in.close();
- 设定输入流的源
- 例子
import java.io.*; public class Example10_4 { public static void main(String args[]) { //定义一个变量 int n=-1; //创建一个数组 byte [] a=new byte[100]; try{ //创建文件 File f=new File("Example10_4.java"); //创建输入流 InputStream in = new FileInputStream(f); //让输入流读取源中的数据 while((n=in.read(a,0,100))!=-1) {//此处执行一个read语句就读取100个字节 String s=new String (a,0,n); System.out.print(s); } //关闭流 in.close();//注意如果不关闭流read方法就会持续读取源中的数据直到抛出异常 } catch(IOException e) { System.out.println("File read Error"+e); } } }
10.3 文件字节输出流
package A;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class A1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
byte[] b = new byte[20];
try {
FileInputStream in = new FileInputStream("aaa.txt");
in.read(b,0,20);
in.close();
FileOutputStream out = new FileOutputStream("bbb.txt");
out.write(b);
out.close();
}catch(IOException e) {
System.out.println("File read error:" + e);
}
}
}
10.4 文件字符输入和输出流
- 概述
- FileInputStream 、FileOutputStream对应的是FileRead、FileWrite字符流,FileReader和FileWrite分别是Read和Write的子类
- 使用字符输入输出流的步骤(和之前的类似)
- 需要注意的是创建字符输入和输出流对象的时候有点特殊
Writer out = new FileWriter(targetFile,true)//意思是不刷新文件 Reader in = new FileReader(sourceFile)
- 需要注意的是创建字符输入和输出流对象的时候有点特殊
例子
import java.io.*;
public class Example10_6 {
public static void main(String args[]) {
File sourceFile = new File("b.txt"); //读取的文件
File targetFile = new File("a.txt"); //写入的文件
char c[] =new char[19]; //char型数组
try{
Writer out = new FileWriter(targetFile,true); //指向目的地的输出流
Reader in = new FileReader(sourceFile); //指向源的输入流
int n = -1;
while((n=in.read(c))!=-1) {
out.write(c,0,n);
}
out.flush();
out.close();
}
catch(IOException e) {
System.out.println("Error "+e);
}
}
}
10.5 缓冲流
- 缓冲流的作用:缓冲流作为上层流有相较于底层流更多的方法,可以更好的执行操作。
- 缓冲流的分类:BufferedReader流和BufferedWriter流。
- 两个流的构造方法
BufferedReader(Reader in);
BufferedWriter(Writer out);
- 缓冲流的使用方法
FileReader inOne = new FileReader("Student.txt");//先创建一个FileReader类的对象 BufferedReader inTwo = BufferedReader(inTwo); //BufferedReader构造方法的参数是Read流对象
- 例子
englih.txt
Example10_7.javaThe arrow missed the target. They rejected the union demand. Where does this road go to?
import java.io.*; import java.util.*; public class Example10_7 { public static void main(String args[]) { File fRead = new File("english.txt");//建立eEnglish文件 File fWrite = new File("englishCount.txt");//建立一个空文件 try{ //使用缓冲流 Writer out = new FileWriter(fWrite); BufferedWriter bufferWrite = new BufferedWriter(out); Reader in = new FileReader(fRead); BufferedReader bufferRead =new BufferedReader(in); //先读后写数据 String str = null; while((str=bufferRead.readLine())!=null) { StringTokenizer fenxi = new StringTokenizer(str); int count=fenxi.countTokens(); str = str+" 句子中单词个数:"+count; bufferWrite.write(str); bufferWrite.newLine(); } bufferWrite.close(); //用完上层流需要关掉 out.close();//没有必要把底层流关掉 //把读取的东西(fWrite文件中的内容)读取输出 in = new FileReader(fWrite); bufferRead =new BufferedReader(in); String s=null; System.out.println(fWrite.getName()+"内容:"); while((s=bufferRead.readLine())!=null) { System.out.println(s); } bufferRead.close(); in.close(); } catch(IOException e) { System.out.println(e.toString()); } } }
10.6 随机流
-
介绍:RandomAccessFile 列创建的流是随机流,他的既可以输入也可以输出
-
RandomAccessFile 类的构造方法
RandomAccessFile (String name,String mode)
name是文件的名字,mode是文件的状态:r只读,rw可读可写
RandomAccessFile(File file,String mode)
file是一个文件,mode也是文件状态(注意此构造方法指向文件的时候不刷新文件) -
随机流的常用方法
seek(long a)
定位RandomAccessFile 流读写的位置
-
注意
- 随机流的读写方法是按照计算机语言不能用记事本打开来看,打开之后也看不懂
- 随机流的读写方法是按字节来读写的,所以使用seek方法的时候要注意
- 目前我还不知道随机流是否能读取文件中的文本内容。
readLine
方法在读取非ASCII编码的文件时会出现乱码,所以需要用iso-8858-1
重新编码放到byte数组中
-
例子:使用随机流倒序输出
Example10_8.javaimport java.io.*; public class Example10_8 { public static void main(String args[]) { RandomAccessFile inAndOut=null; int data[]={1,2,3,4,5,6,7,8,9,10}; try{ inAndOut=new RandomAccessFile("tom.dat","rw"); for(int i=0;i<data.length;i++) { inAndOut.writeInt(data[i]); } for(long i=data.length-1;i>=0;i--) { //一个int型数据占4个字节,inAndOut从 inAndOut.seek(i*4); //文件的第36个字节读取最后面的一个整数, System.out.printf("\t%d",inAndOut.readInt()); //每隔4个字节往前读取一个整数 } inAndOut.close(); } catch(IOException e){} } }
-
例子2:使用随机流输出含有非ASCII码的内容
import java.io.*; public class Example10_9 { public static void main(String args[]) { RandomAccessFbyile in=null; try{ in=new RandomAccessFile("Example10_9.java","rw"); long length=in.length(); //获取文件的长度 long position=0; in.seek(position); //将读取位置定位到文件的起始 while(position<length) { String str=in.readLine(); byte b[]=str.getBytes("iso-8859-1"); str=new String(b); position=in.getFilePointer(); System.out.println(str); } } catch(IOException e){} } }
10.7 数组流
-
介绍:源和目标可以是文件也可以是内存。
-
字节数组输入流
ByteArrayInputStream
是他的类- 构造方法
ByteArrayInputStream(byte[] buf)
以buf作为源ByteArrayInputStream(byte[] buf,int offset,int length)
从数组offset处按顺序取length个字节单元
-
字节数组输出流
ByteArrayOutputStrea
是它的类- 构造方法
ByteArrayOutputStream()
:向缓冲区开辟一个32字节的数组ByteArrayOutputStream(int size)
:想缓冲区开辟一个size大小的数组
- 其他方法
public byte[] toByteArray();
:可以返回缓冲区中的全部字节
-
例子
import java.io.*; public class Example10_10 { public static void main(String args[]) { try { //创建字节数组输出流的对象 ByteArrayOutputStream outByte=new ByteArrayOutputStream(); //将一段字符串转化为数组,作为输出的源 byte [] byteContent="mid-autumn festival".getBytes(); //调用write方法,将此数组输出到内存中 outByte.write(byteContent); //创建字节输入流 ByteArrayInputStream inByte=new ByteArrayInputStream(outByte.toByteArray()); //创建一个和上边等长的字节数组作为目标文件进行输入 byte backByte []=new byte[outByte.toByteArray().length]; //调用read方法,从缓冲区读取字节到backByte中 inByte.read(backByte); //转换为String对象输出 System.out.println(new String(backByte)); //以下是用字符数组输入输出流进行操作 CharArrayWriter outChar=new CharArrayWriter(); char [] charContent="中秋快乐".toCharArray(); outChar.write(charContent); CharArrayReader inChar=new CharArrayReader(outChar.toCharArray()); char backChar []=new char[outChar.toCharArray().length]; inChar.read(backChar); System.out.println(new String(backChar)); } catch(IOException exp){} } }
10.8 数据流
-
介绍:DataInputStream和DataOutPut类创建的对象称为数据输入输出流。
-
优点:数据流允许程序按照与机器无关的风格读取Java原始数据,即不必关心字节的问题。
-
数据流的构造方法
DataInputStream(InputStream in)
创建数据流以out为底层流DataOutputStream(OutputStream out)
:创建数据流以in为底层流
-
例子
import java.io.*; public class Example10_11 { public static void main(String args[]) { File file=new File("apple.txt"); try{ FileOutputStream fos=new FileOutputStream(file); DataOutputStream outData=new DataOutputStream(fos); outData.writeInt(100); outData.writeLong(123456); outData.writeFloat(3.1415926f); outData.writeDouble(987654321.1234); outData.writeBoolean(true); outData.writeChars("How are you doing "); } catch(IOException e){} try{ FileInputStream fis=new FileInputStream(file); DataInputStream inData=new DataInputStream(fis); System.out.println(inData.readInt()); //读取int数据 System.out.println(inData.readLong()); //读取long数据 System.out.println(+inData.readFloat()); //读取float数据 System.out.println(inData.readDouble()); //读取double数据 System.out.println(inData.readBoolean());//读取boolean数据 char c = '\0'; while((c=inData.readChar())!='\0') { //'\0'表示空字符。 System.out.print(c); } } catch(IOException e){} } }