1.输入/输出流
1.1 I/O流概念
库函数:java.io
输入:数据流入程序
输出:数据从程序流出
- 打开一个流
- 读/写流
- 关闭流
1.2 I/O流相关类
- 按流的方向分
- 输入流
- 输出流
- 按流的内容分类
- 面向字符流:专门处理用字符数据
- 面向字节流:用于通用的二进制数据
- 字节流是最基础的,字符流也是字节流
弄清JAVA中字节与字符
- 按流的分工分类
- 节点流:直接与目标相连
- 处理流:不直接与目标相连,基于已有的流构造
面向字符的流
- 源或目标通常是文本文件
- 抽象类Reader和Writer是所有字符流的父类
面向字节的流
- 如果数据源或目标含有非字符数据,必须用字节流来输入/输出
- 比如图片、声音
标准输入输出流
标准输入输出对象:in 、out 、err
import java.io.*; public class TEST {public static void main(String args[])throws IOException{BufferedReader r = new BufferedReader(new InputStreamReader(System.in));String s = r.readLine();//hello worldf sdfas JKGJHSystem.out.println(s);//hello worldf sdfas JKGJH} }
- 重定向
- setIn(InputStream):设置标准输入流
- setOut():设置标准输出流
- setErr():设置标准错误输出流
import java.io.*; public class TEST {public static void main(String args[])throws IOException{BufferedInputStream inn=new BufferedInputStream(new FileInputStream("d:\\aa\\input.java.txt"));PrintStream outt = new PrintStream(new BufferedOutputStream(new FileOutputStream("d:\\aa\\test")));System.setIn(inn);System.setOut(outt);System.setErr(outt);BufferedReader br = new BufferedReader(new InputStreamReader(System.in));String s = br.readLine();System.out.println(s);outt.close(); } }
- 处理流
- 不直接与数据源或目标相连,而是基于另一个流来构造
- 从流中读取数据的同时对数据进行处理,例如:
- InputStreamReader 读取字节并转换字符
- BufferedReader对另一个流产生的数据进行缓冲
- 处理流类的构造方法中,通常需要传入一个节点流作为参数
- IO异常
- ???????多数IO方法在遇到错误时会抛出异常,因此调用这些方法时必须:
- ???????在方法头声明抛出IOException
- 或在try块中执行IO,然后捕获IOException
2.文件读写
2.1 File类
- 表示磁盘文件信息
- 定义了一些与平台无关的方法来操纵文件
- File类的对象可以作为文件流的参数
???????
2.2 读写文本文件
2.2.1 FileWriter
通常使用 FileWriter 或 BufferedWriter 类,如果需要写入的内容很多,用后者可以提高效率
void write(int n) void write(char c[]) void write(char c[],int offset,int len) void write(String s) void write(String s,int offset,int len)BufferedWriter提供了一个newLine()方法用于换行
package test;
import java.io.*;
//读写文本文档
public class test {public static void main(String args[]) throws IOException///main方法中抛出IO异常{String fileName="C:\\Hello.txt";FileWriter writer = new FileWriter(fileName);writer.write("Hello\n");writer.write("This is my first file\n");writer.write("You can see this is done.\n");writer.write("输入一行中文也可以\n");writer.close(); }
}
- 打开c盘根目录下的hello.txt文件
如果没有换行的话 可以试一下\r\n
- 每次运行这个程序,都将删除已经存在的“Hello.txt”文件,创建一个新的同名文件
- FileWriter的构造方式有五个,见上
- FileWriter类的write方法想文件中写入字符
package test;
import java.io.*;
//读写文本文档
public class test {public static void main(String args[]) throws IOException///main方法中抛出IO异常{String fileName="C:\\Hello.txt";try{//将所有的IO操作放入try块中FileWriter writer = new FileWriter(fileName,true);//追加在后面,默认false,即覆盖重写writer.write("Hello\n");writer.write("This is my first file\n");writer.write("You can see this is done.\n");writer.write("输入一行中文也可以\n");writer.close();}catch(IOException e){System.out.println("Problem writing:"+e.getMessage());}}
}
- 如果修改文件属性为只读,再运行本程序,就会出现错误
2.2.2 BufferedWriter
如果需要输入的内容很多,就应该使用更为高效的缓冲器流类 BufferedWriter
BufferedWriter 多一个newLine() 方法用于换行
package test;
import java.io.*;
//读写文本文档
public class test {public static void main(String args[]) throws IOException///main方法中抛出IO异常{String fileName="C:\\newHello.txt";try{//将所有的IO操作放入try块中BufferedWriter writer = new BufferedWriter(new FileWriter(fileName));writer.write("Hello!");writer.newLine();writer.write("This is a new text file using BufferdWriter");writer.newLine();writer.close();}catch(IOException e){System.out.println("Problem writing:"+e.getMessage());}}
}
package test;
import java.io.*;
import java.util.*;
//读写文本文档
public class test {public static void main(String args[]) throws IOException///main方法中抛出IO异常{String fileName="C:\\grade.txt";try{Scanner scan = new Scanner(System.in);BufferedWriter writer = new BufferedWriter(new FileWriter(fileName));System.out.println("请输入5门课程成绩");for(int i=1;i<=5;i++){String s=scan.nextLine();writer.write(s);writer.newLine();}writer.close();}catch(IOException e){System.out.println("Problem writing:"+e.getMessage());}}
}
package test;
import java.io.*;
import java.util.*;
//读写文本文档
public class test {public static void main(String args[]) throws IOException///main方法中抛出IO异常{String fileName="C:\\grade.txt";try{Scanner scan = new Scanner(System.in);BufferedWriter writer = new BufferedWriter(new FileWriter(fileName));System.out.println("请输入多门课程成绩,以0结束");String line=scan.nextLine();while(!line.equals("0")){writer.write(line);writer.newLine();line=scan.nextLine();}writer.close();}catch(IOException e){System.out.println("Problem writing:"+e.getMessage());}}
}
package test;
import java.io.*;
import java.util.*;
//读写文本文档
public class test {public static void main(String args[]) throws IOException///main方法中抛出IO异常{String fileName="C:\\grade.txt";try{Scanner scan = new Scanner(System.in);BufferedWriter writer = new BufferedWriter(new FileWriter(fileName,true));//不覆盖System.out.println("请输入多门课程成绩,以0结束");String line=scan.nextLine();while(!line.equals("0")){writer.write(line);writer.newLine();line=scan.nextLine();}writer.close();}catch(IOException e){System.out.println("Problem writing:"+e.getMessage());}}
}
2.2.2 BufferedReader 、FileReader
- 通常使用FileReader或BufferedReader类,如果需要读取的内容很多,用后者提高效率
int read() int read(char c[]) int read(char c[],int offset,int len)
- Bufferedreader多提供了一个readLine()方法用于读取一行
- 判断文件末尾的方法
- Reader类的read()返回-1时;否则返回字符的编码
- BufferedReader类的readLine()为null时
package test;
import java.io.*;
import java.util.*;
//读写文本文档
public class test {public static void main(String args[]) throws IOException///main方法中抛出IO异常{String fileName="C:\\newHello.txt";try{FileReader reader =new FileReader(fileName);int c;while((c=reader.read())!=-1){System.out.print((char)c);}reader.close();}catch(IOException e){System.out.println("Problem writing:"+e.getMessage());}}
}
package test;
import java.io.*;
import java.util.*;
//读写文本文档
public class test {public static void main(String args[]) throws IOException///main方法中抛出IO异常{String fileName="C:\\newHello.txt";try{BufferedReader reader =new BufferedReader(new FileReader(fileName));String line=reader.readLine();while(line!=null){System.out.println(line);line=reader.readLine();}}catch(IOException e){System.out.println("Problem writing:"+e.getMessage());}}
}
package test;
import java.io.*;
import java.util.*;
//读写文本文档
public class test {public static void main(String args[]) throws IOException///main方法中抛出IO异常{String fileName="C:\\grade.txt";try{BufferedReader reader =new BufferedReader(new FileReader(fileName));String line=reader.readLine();int total=0,num=0;while(line!=null){String a[]=line.split(" ");//System.out.println(a[1]);total=total+Integer.parseInt(a[1]);num++;line=reader.readLine();}reader.close();System.out.println("总成绩为:"+total+"平均成绩为:"+total/(double)num);}catch(IOException e){System.out.println("Problem writing:"+e.getMessage());}}
}
2.3 读写二进制文件
- 原则上,所有文件都是由字节组成的
- 如果文件中的内容应被解释为字符,则文件被称为文本文件,否则就是二进制文件
- 注意:一些文字处理软件(Word)产生的文件中,数据要被解释为文字、格式、图形和其他非字符信息,因此,这样的文件是二进制文件,不能用Reader流正确读取
为什么需要二进制文件 ?
- 输入输出更快
- 比文本文件小很多
- 有些数据不容易被表示为字符
2.3.1 写二进制文件
常用来写文件的输出流类:
- FileOutputStream
- DataOutputStream
- BufferedOutputStream
常用写字节的方法
- void write(int n)
- void write(byte b[])
- void write(byte b[],int offset,int len)
抽象类OutputStream
- 派生类FileOutputStream
- 用于一般目的的输出
- 用于成组字节输出
- 派生类DataOutputStream
- 具有写各种基本数据类型的方法
- 将数据写到另一个输出流
- 它在所有的计算机平台上使用同样的数据格式
- 其中size方法,可作为计数器,统计写入的字节数
- 派生类BufferedOutputStream
- 写二进制文件的缓冲流类
- 类似于文本文件中的BufferedWriter
- 对于大量数据写入可以提高效率
package test;
import java.io.*;
import java.util.*;
public class test {public static void main(String args[]) {String fileName = "c:\\data1.dat";int value0=255,value1=0,value2=-1;try{DataOutputStream writer = new DataOutputStream(new FileOutputStream(fileName));writer.writeInt(value0);System.out.println(writer.size());writer.writeInt(value1);System.out.println(writer.size());writer.writeInt(value2);System.out.println(writer.size());writer.close();}catch(IOException iox){System.out.println("Problem writing"+iox.getMessage());}}
}
package test;
import java.io.*;
import java.util.*;
public class test {public static void main(String args[]) {String fileName = "mixedTypes.dat";try{DataOutputStream writer = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(fileName)));writer.writeInt(0);System.out.println(writer.size()+" bytes have been written");writer.writeDouble(32.21);System.out.println(writer.size()+" bytes have been written");writer.writeBytes("java");System.out.println(writer.size()+" bytes have been written");writer.close();}catch(IOException iox){System.out.println("Problem writing"+iox.getMessage());}}
}
2.3.2 读二进制文件
常用来读文件的输入流类:
- FileInputStream
- DataInputStream
- BufferedInputStream
常用读二进制文件的方法:
- int read();
- int read(byte b[]);
- int read(byte b[],int offset,int len);
package test;
import java.io.*;
import java.util.*;
public class test {public static void main(String args[]) {String fileName = "c:\\data1.dat";int sum=0;try{DataInputStream reader = new DataInputStream( new BufferedInputStream (new FileInputStream(fileName)));sum+=reader.readInt();sum+=reader.readInt();sum+=reader.readInt();System.out.println("The sum is:"+sum);}catch(IOException iox){System.out.println("Problem writing"+iox.getMessage());}}
}
package test;
import java.io.*;
import java.util.*;
public class test {public static void main(String args[]) throws IOException{String fileName = "c:\\data1.dat";DataInputStream reader = new DataInputStream( new BufferedInputStream (new FileInputStream(fileName)));int sum=0;try{while(true){sum+=reader.readInt();}}catch(IOException eof){System.out.println("The sum is:"+sum);reader.close();}}
}
2.4 随机存储文件读写
很多时候,要求程序能够快速、直接地访问文件中的特定信息,这时就需要用到“随机存取文件”
- 流文件往往是依次、顺序读取的,要想查询某部分特定信息,必须从头第一遍文件,直接找到位置
- 随机存取文件嫰狗狗方便直接定位到特定位置
- 存取文件必须要指定的格式规则
- RandomAccessFile类用于随机存取文件
- 可直接跳到任意文件的任意位置读/写数据
- 可在随机文件中插入数据,而不被破坏文件的其他数据
- 在等长记录格式文件的随机读取时有很大优势,但仅限于操作文件,不能访问其他IO设备,如网路、内存映像
- 有一个位置指示器,指向当前读写处的位置。刚打开文件时,文件指示器向文件的开头处
- public int skipBytes(int n):把文件指针移动到指定的位置
- public void seek(long):移动文件指针到指定的位置
- public native long getFilePointer():得到当前的文件指针
- 构造方法
- RandomAccessFile(File file,String mode) throws FileNotFounException
- RandomAccessFile(String name,String mode) throws FileNotFounException
- mode指名要执行操作的权限
- 常用方法
- length():返回文件的长度,即字节数
- read():从文件中读取一字节,如遇到结尾,则返回-1
- readDouble():读取八个字节(double数据)
- writeChar(int v):写入一个字符,两个字节,高位先写入
- writerInt(int v):写入四个字节的int型数字
package test;
import java.io.*;
import java.util.*;
public class test {public static void main(String args[]) throws IOException{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--){inAndout.seek(i*4);//一个int占据四个字节System.out.printf(" %d",inAndout.readInt());}inAndout.close();}catch(IOException e){}}
}
package test;import java.io.*;
import java.util.*;public class test {public static void main(String args[]) throws IOException {try {String fileName1="c:\\grade.txt";String fileName2="c:\\sortedgrade.txt";BufferedReader reader=new BufferedReader(new FileReader(fileName1));BufferedWriter writer=new BufferedWriter(new FileWriter(fileName2));String line=reader.readLine();String grade[][]=new String [100][];////这里初始化了100个null String 所以后面要用cnt而不是String.length()代替int cnt=0;while(line!=null){grade[cnt]=line.split(" ");cnt++;line=reader.readLine();}//sort(grade);for(int i=0;i<cnt;i++){for(int j=i+1;j<cnt;j++){if(Integer.parseInt(grade[i][1])>Integer.parseInt(grade[j][1])){String s1,s2;s1=grade[i][0];grade[i][0]=grade[j][0];grade[j][0]=s1;s2=grade[i][1];grade[i][1]=grade[j][1];grade[j][1]=s2;}}}for(int j=0;j<cnt;j++){System.out.println(j+1+" "+grade[j][0]+" "+grade[j][1]);writer.write(j+1+" "+grade[j][0]+" "+grade[j][1]);writer.newLine();}reader.close();writer.close();} catch (IOException e) {}}}
package test;import java.io.*;
import java.util.*;public class test {public static void main(String args[]) throws IOException {File file = new File("C:\\newFile");File[] filenames = file.listFiles();for (int i = 0; i < filenames.length; i++) {if (filenames[i].getName().endsWith(".txt")) {BufferedReader reader = new BufferedReader(new FileReader(file+ "\\" + filenames[i].getName()));String line = reader.readLine();while (line != null) {System.out.println(line);line = reader.readLine();}reader.close();}else//移动jpg文件{BufferedInputStream input= new BufferedInputStream(new FileInputStream("C:\\newFile\\"+filenames[i].getName()));BufferedOutputStream output=new BufferedOutputStream(new FileOutputStream("C:\\newFile\\"+filenames[i].getName()));int in=input.read();while(in!=-1){output.write(in);in=input.read();}output.flush();output.close();input.close();}}}}