IO输入与输出 上
第七讲 IO/输入与输出
FILE类
RandomAccessFile 类
各种节点流类
字符编码
各种过滤流与包装类
IO类的相关应用
File 类
File类是IO包中唯一代表磁盘文件本身信息的类,而不是文件中的内容。
File 类定义了一些与平台无关的方法来操作文件,例如,创建、删除文件和重命名文件。
Java中的目录被当作一种特殊的文件使用,list方法可以返回目录中的所有子目录和文件名。
编程举例:判断某个文件是否存在,存在删除,不存在创建
import java.io.*;
import java.util.Date;
public class FileTest{
public static void main(String[] args){
File f=new File("1.txt");
if (f.exists())
{
f.delete();
System.out.println("de!!!!!");
}
else
{
try{
f.createNewFile();
}
catch(Exception e)
{
e.printStackTrace();
}
}
System.out.println("File name:"+f.getName());
System.out.println("File path:"+f.getPath());
System.out.println("File abs path:"+f.getAbsolutePath());
System.out.println("File Parent:"+f.getParent());
System.out.println(f.exists()?"exist":"not exist");
System.out.println(f.canRead()?"read":"not read");
System.out.println(f.isDirectory()?"directory":"notdiretory");
System.out.println("File last modified:"+new Date(+f.lastModified()));
}
}
RandomAccessFile 类
RandomAccessFile类提供了众多的文件访问方法
RandomAccessFile类支持“随机访问”方式。
RandomAccessFile类在随机读写等长记录格式的文件时有很大的优势
RandomAccessFle类仅限于操作文件,不能访问其他的IO设备,如网络,内存映像等。
无论读还是写都是以文件指示器的位置开始
两种构造方法:
new RandomAccessFile(f."rw");//读写方式
new RandomAccessFile(f."r");//只读方式
编程实例:往文件中写入三名员工的信息,每个员工含有姓名和年龄两个字段,然后按照第二名、第一名、第三名的先后顺序读出员工信息。
import java.io.*;
public class Employee {
public String name=null;
public int age=0;
public static final int LEN=8;
public Employee(String name,int age)
{
if(name.lengh()>LEN)
{
this.name=name.sustring(0,LEN)
else
{
while(name.lengh<LEN)
{ name+="/uooo"
}
}
}
this.name=name;
this.age=age;
}
}
public class RandomFileTest{
public static void main(Sting[] args){
Employee e1=new Employee("zhangsan",23);
Employee e2=new Employee("lisi",24);
Employee e3=new Employee("wangwu",25);
RandomAccessFile ra=new RandomAccessFile("employee.txt","rw");
ra.writeChars(e1.name.getBytes());//以字节的方式写入
ra.writeInt(e1.age);
ra.writeChars(e2.name.getBytes());
ra.writeInt(e2.age);
ra.writeChars(e3.name.getBytes());
ra.writeInt(e3.age);
ra.close();
String strName="";
RandomAccessFile raf= new RandomAccessFile("employee.txt","r");
raf.skipBytes(Employee.LEN*2+4);//跳转十二个字节
for(int i=0;i<Empoyee.LEN;i++)
{
strName+=raf.readChar();
}
System.out.println(strNametrim()+ ":"+ raf.read());
raf.seek(0);//读取第一个员工信息
len=raf.read(buf);
strName=new String(buf,0,len);
System.out.println(strName.trim()+":" +raf.readInt());
String strName="";
raf.skipBytes(Employee.LEN*2+4);
for(int i=0;i<Empoyee.LEN;i++)
{
strName+=raf.readChar();
}
System.out.println(strNametrim()+ ":"+ raf.read());
raf.close();//关闭文件对象
}
}
流是字节序列的抽象概念
文件是数据的静态存储形式,而流是指数据传输时的形态
流类分为两大类:节点流类和过滤流类
IputStream类
程序可以从中连续读取字节的对象叫输入流,在java中,用inputStream类来描述所有输入流的抽象概念。
InputStream类的方法:
int read():读取流中的第一个字节,并返回int型 见,数据中断会堵塞程序执行
int read():从流中读取b长度的字节
int read(byte[]b,int off,int len)
long skip(long n)
int available():检查文件中是否有可读取的数据
void marking(int reading)
void reset()
boolean markSupperted()
void close()
OutputStream 类
程序可以向其连续写入字节的对象叫输出流。
OutputStream 的方法
void write(int b):就是将一个整数的最低的那个字节的内容写到输出流中,最高自己部分被舍弃。
void write(byte[] b):将数组b中的所有内容都写入到输出流中
void write(byte[] b,int off,int len)
void flush():用于将内存缓冲区中的内容彻底的清空并输出到IO设备当中(可以强制)
void close()
FileInputStream 与FileOutputStream类
FileInputStream和FileOutputStream类分别用来创建磁盘文件的输入流和输出流对象,通过他们的构造函数来指定文件路径和文件名。
创建FileInputStream实例对象时,指定的文件应当是存在和可读的。创建FileOutputStream实例对象时,如果指定的文件已经存在,这个文件中的原来内容将被覆盖。
对一个磁盘文件创建FileInputStream对象的两种方式
创建FileoutputStream实例对象时,可以指定还不存在的文件名,不能指定一个已被其他程序打开了的文件。
编程举例:
用FileOutputStream类向文件中写入一个串字符,然后用FileInputStream读出写入的内容
import java.io.*;
public class FileStream{
public static void main (String[] args)throws Exception {
FileOutputStream out = new FileOuputStream("hello.txt");
out.write("www.it315.org".getBytes());
out.close();
byte[] buf=new byte[1024];
File f=new File("hello.txt");
FileInputStream in=new FileInputStream(f);
int len=in.read(buf);
System.out.println(new String(buf,0,len))
}
}
Reader 与Writer 类
Reader和Writer是所有字符流类的抽象基类,用于简化对字符串的输入与输出编程,即用于读写文本数据
二进制文件和文本文件的区别。
文本文件时二进制文件的一个特例
如果一个文件专用于存储文本字符没有其他东西 就是文本文件,其他为二进制文件。
用FileWriter类向文件中写入一个字符串,然后用FileReader读出写入的内容。
import java.io.*;
public class FileStream2{
public static void main (String[] args)throws Exception {
FileWriter out=new FileWriter("hello2.txt");
out.witer("www.it315.org");
out.close();
char [] buf=new char[1024]
FileReader in=new FileReader("hello2.txt");
int len=in. read(buf);
System.out.println(new String(buf.0.len));
}
}
read()方法不能直接读字符串,只能读取字符,先要创建字符数组。
PipedInputStream 与 PipedOutputStream 类
用于在应用程序中的创建管道通信
编程实例
import java.io.*;
public class Sender extends Thread{
private PipedOutputStream out=new PipedOutputStream ();
public PipedOutputStream getOutputStream()
{
return out;
}
public void run()
{
String strInfo=new String("hello receiver");
try{
out.wrier(strInfo.getBytes();
out.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public class Receiver extends Thread{
private PipedInputStream out=new PipedInputStream ();
public PipedInputStream getInputStream()
{
return out;
}
public void run()
{
String strInfo=new String("hello receiver");
byte[] buf=new byte[1024];
try{
in.read(buf);
System.out.println("the following message come from sender:/n "+new String(buf,0,len));
in.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public class PipedStreamTest throws Exception {
public static void main(String[] args){
Sender t1=new Sender();
Receiver t2=new Receiver();
PipedOutputStream out= t1.getOutputStream();
PipedInputStream in=t2.getInputStream();
out.connect(in);
t1.start();
t12.start();
}
}
PipedWriter和PipedReader 类。
使用管道流类,可以实现各个程序模块之间的松耦合通信。
ByteArrayInputStream 与ByteArrayOutputStream类,用于以IO流的方式来完成对字节数组内容的读写,来支持类似内存虚拟文件或者内存映像文件的功能。
ByteArrayInputStream的两个构造函数:
ByteArrayInputStream(byte[] buf)
ByteArrayInputStream(byte[] buf,int offset,int lengh)
ByteArrayOutputStream
ByteArrayOutputStream()
ByteArrayOutputStream(int)
编写一个把输入流中所有英文字母变成大写字母,然后将结果写入到一个输出流对象。用这个函数来将一个字符串中的所有字符转换成大写。
public class ByteArrayTest{
public static void main(String[] args){
String tmp="abcdefghijklmnopqrst"
byte [] src=tmp.getBytes();
ByteArrayInputStream input=new ByteArrayInputStream(src);
ByteArrayOutputStream output=new ByteArrayOutputStream();
transform(input,output);
byte[] result=output.toByteArray();
System.out.println(new String(result));
}
public static void transform(InputStream in,OutputStream out)
{
int ch= 0;
try
{
while(ch=in.read()!=-1)
{
int upperCh=Character.toUpperCase((char)ch);
out.write(upperCh);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
StringReader类和StringWriter类来以字符IO流的方式处理字符串
重视IO程序代码的复用
System.in连接到键盘,是inputStream类型的实例对象。System.out连接到显示器,是PrintStream类的实例对象。
不管各种底层物理设备用什么方式实现数据的终止点,InputStream的read方法总是返回-1来表示输入流的结束。
在windows下,按下Ctrl+z,在linux下是Ctrl+D组合键可以产生键盘输入流的结束编辑
建议:要编程从键盘上连续读取一大段数据时,应尽量将读取数据的过程放在函数中完成,使用-1来作为键盘输入的结束点。在函数中编写的程序代码不应该直接使用Sys.in读取数据,而是用一个InputStream类型的形式参数对象来读取数据,然后将System.in 作为实参传递给InputStream类型的形式参数来调用该函数。