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 JKGJH System.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();
}
}
}
}