您的位置:首页 > 编程语言 > Java开发

Java I/O

2015-12-11 21:30 711 查看
课程 Java面向对象程序设计

一、实验目的

掌握数据流的使用

二、实验环境

1、微型计算机一台

2、WINDOWS操作系统,Java SDK,Eclipse开发环境

三、实验内容

1、掌握FileInputStream、FileOutStream、FileReader、FileWriter的使用,并编写程序,实现数据的输入和输出。

2、掌握BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter的使用,并编写程序,实现数据的输入和输出。

3、掌握InputStreamReader、OutputStreamWriter的使用,并编写程序,实现数据的输入和输出。

4、掌握DataInputStream、DataOutputStream的使用,并编写程序,实现数据的输入和输出。

5、掌握PrintStream、PrintWriter的使用,并编写程序,实现数据的输入和输出。

6、掌握ObjectInputStream、ObjectOutputStream的使用,并编写程序,实现数据的输入和输出。

四、实验步骤和结果

1、掌握FileInputStream、FileOutStream、FileReader、FileWriter的使用,并编写程序,实现数据的输入和输出。

以上这四个类是属于文件流,文件流是指那些专门用于操作数据源中的文件的流。下面根据它们读写数据时的操作单位,分成两组。

(1)FileInputStream和FileOutputStream是以字节为操作单位的文件输入流和文件输出流。利用这两个类可以对文件进行读写操作。

① 使用FileInputStream类来读取指定文件的数据:

编写代码(FileInputStreamTest.java)如下:

package FileStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
//使用FileInputStream类来读取数据源中的数据
public class FileInputStreamTest {
public static void main(String[] args) {
FileInputStream fin=null;
try {
//step1:创建一个连接到指定文件的FileInputStream对象
fin=new FileInputStream("D:\\IOTest\\source.txt");
System.out.println("可读取的字节数:"+fin.available()+"字节");
//step2:读数据:一次读取一个字节的数据,返回的是读到的字节
int i=fin.read();
while (i!=-1) {  //若遇到流的末尾,会返回-1
System.out.print((char)i);
i=fin.read(); //再读
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {  //捕获I/O异常
e.printStackTrace();
}finally{
try {//关闭输入流
if (null!=fin) {
fin.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}


其中,“D:\IOTest\source.txt”文件的内容如下:



运行以上这个程序,在控制台的输出结果为:



可以看到,输出结果中中文字符会乱码,因为一个中文字符是由两个字节编码的。

② 使用FileOutputStream类往指定文件中写入数据:

编写代码(FileOutputStreamTest.java)如下:

package FileStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/*使用FileOutputStream类往指定文件中写入数据*/
public class FileOutputStreamTest {
public static void main(String[] args) {
FileOutputStream out=null;
try {
//Step1:创建一个向指定名的文件中写入数据的FileOutputStream
//第二个参数设置为true表示:使用追加模式添加字节
out=new FileOutputStream("D:\\IOTest\\shenxiaolin.txt",true);
//Step2:写数据
out.write('#');
out.write("105032013120_沈".getBytes());
out.write("Hello World 你好".getBytes());
//Step3:刷新输出流
out.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) { //捕获IO异常
e.printStackTrace();
}finally{
if (out!=null) {
try {
out.close(); //Step:4:关闭输出流
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}


运行这个程序后,可以在D:\IOTest\看到有一个“shenxiaolin.txt”的文件存在,它的内容如下:



(2)FileReader和FileWriter是以字符为操作单位的文件输入流和文件输出流。因此,FileReader和FileWriter适合用来操作字符文本文件。

如下代码示例(FileReaderAndFileWriterTest.java)实现复制字符文本文件复制的功能:

package FileStream;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class FileReaderAndFileWriterTest {
//用 FileReaderAndFileWriter实现复制字符文本文件复制的功能
/**     * @param arg */
public static void main(String[] args) {
FileReader fr=null;
FileWriter fw=null;
int c=0;
try {
//创建I/O流对象
fr=new FileReader("D:\\IOTest\\shenxiaolin.txt");
fw=new FileWriter("D:\\IOTest\\shenxiaolin2.txt");
while ((c=fr.read())!=-1) {//从源文件中读取字符
fw.write(c);
}
fw.flush();//刷新输出流
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}finally{
//关闭所有的I/O流对象
try {
if (null!=fw) {
fw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (null!=fr) {
fr.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}

}

}


运行上述程序后,在D:\IOTest目录下新产生一个shenxiaolin2.txt的文件,其内容与shenxialoin.txt的内容完全相同。结果如下截图所示:



2、掌握BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter的使用,并编写程序,实现数据的输入和输出。

(1)BufferedInputStream和BufferedOutputStream:是针对字节的缓冲输入和输出流。

以下代码(BufferedInputStreamAndBufferedOutputStreamTest.java)是用

BufferedInputStream和BufferedOutputStream实现字节文本文件复制的功能:

package FileStream;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class BufferedInputStreamAndBufferedOutputStreamTest {
public static void main(String[] args) {
BufferedInputStream bfiStream=null;
BufferedOutputStream bfoStream=null;
try {
bfiStream=new BufferedInputStream(new FileInputStream("D:\\IOTest\\source.txt"));
bfoStream=new BufferedOutputStream(new FileOutputStream("D:\\IOTest\\shenxiaolinbuffOutStream.txt"));
int i;
while ((i=bfiStream.read())!=-1) {
bfoStream.write((char)i);
}
bfoStream.flush();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if (bfoStream!=null) {
bfoStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(null!=bfiStream){
bfiStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}


运行上述程序后,在D:\IOTest目录下新产生一个

shenxiaolinbuffOutStream.txt的文件,其内容与source.txt的内容完全相同。结果如下截图所示:



(2)BufferedReader和BufferedWriter:是针对字符的缓冲输入和输出流。

以下代码(BufferedReaderAndBufferedWriterTest.java)是用

BufferedReader和BufferedWriter实现字符文本文件复制的功能:

package FileStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
//用BufferedReader和BufferedWriter实现字符文本文件复制的功能:
public class BufferedReaderAndBufferedWriterTest {
public static void main(String[] args) {
BufferedReader br=null;
BufferedWriter bw=null;
try {
//创建缓冲流对象:它是过滤流,是对节点流的包装
br=new BufferedReader(new FileReader("D:\\IOTest\\source.txt"));
bw=new BufferedWriter(new FileWriter("D:\\IOTest\\shenxiaolinBF.txt"));
String str=null;
while ((str=br.readLine())!=null) {
//一次性读取字符文本文件的一行字符
bw.write(str);//一次写入一行字符串
bw.newLine();//写入行分隔符
}
bw.flush();//刷新缓冲区
} catch (IOException e) {
e.printStackTrace();
}finally{
//关闭I/O流对象
try {
if (null!=bw) {
bw.close();//关闭过滤流时,会自动关闭它所包装的底层节点流
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}


运行上述程序后,在D:\IOTest目录下新产生一个shenxiaolinBF.txt的文件,其内容与source.txt的内容完全相同。结果如下截图所示:



3、掌握InputStreamReader、OutputStreamWriter的使用,并编写程序,实现数据的输入和输出。

(1)InputStreamReader用于将字节流中读取到的字节按指定字符集解码成字符。它需要与InputStream“套接”。

以下(InputStreamReaderByteToCharTest.java)是使用InputStreamReader将字节输入流转换成字符输入流:

package FileStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class InputStreamReaderByteToCharTest {
public static void main(String[] args) {
System.out.println("请输入信息(退出请输入e或者exit):");
//把“标准”输入流(键盘输入)这个字节流包装成字符流,再包装成缓冲流
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String s=null;
try {
while ((s=br.readLine())!=null) {
//读取用户输入的一行数据-->阻塞程序
if (s.equalsIgnoreCase("e")||s.equalsIgnoreCase("exit")) {
System.out.println("安全退出!");
break;
}
//将读取到的整行字符串转成大写输出
System.out.println("-->:"+s.toUpperCase());
System.out.println("继续输入信息");
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if (null!=br) {
br.close();//关闭过滤流时,会自动关闭它包装的底层节点流
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}


运行程序,结果如下所示:



(2)OutputStreamWriter用于将要写入到字节流中的字符按指定字符集解码成字节。它需要与OutputStream“套接”。

以下(OutputStreamWriterCharToByteTest.java)是使用OutputStreamWriter将字符输入流转换成字节输入流:

package FileStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
public class OutputStreamWriterCharToByteTest {
public static void main(String[] args) {
System.out.println("请输入信息:");
BufferedReader bufr1=new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw1=new BufferedWriter(new OutputStreamWriter(System.out));
String line1=null;
try {
while ((line1=bufr1.readLine())!=null) {
if ("over".equals(line1))   break;
bufw1.write(line1.toUpperCase());
bufw1.newLine();
bufw1.flush();
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if (null!=bufw1) {
bufw1.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
try {
if (null!=bufr1) {
bufr1.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}


运行结果如下所示:



4、掌握DataInputStream、DataOutputStream的使用,并编写程序,实现数据的输入和输出。

(1)DataInputStream 用来读取基本数据类型的数据:

以下代码(DataInputStreamAndDataOutputStreamTest.java)是数据流在内存中的使用示例:

package FileStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
//数据流在内存中的使用示例
import java.io.DataOutputStream;
public class DataInputStreamAndDataOutputStreamTest {
public static void main(String[] args) {
ByteArrayOutputStream baos=new ByteArrayOutputStream();
DataOutputStream dos=new DataOutputStream(baos);
try {
dos.writeDouble(Math.random());
dos.writeBoolean(true);
dos.writeChars("shenxiaolin|Java|\t");
dos.writeUTF("沈");
ByteArrayInputStream bais=new ByteArrayInputStream(baos.toByteArray());
System.out.println("可读取的字节数是:"+bais.available());
DataInputStream dis=new DataInputStream(bais);
System.out.println(dis.readDouble());
System.out.println(dis.readBoolean());
char[] temp=new char[200];
//开辟空间200
int len=0;
char c=0;
while ((c=dis.readChar())!='\t') {
//读取字符
temp[len] = c;
len++;
}
String name=new String(temp,0,len);
System.out.println(name);
System.out.println(dis.readUTF());
dos.close();
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}


运行结果如下所示:



(2)DataOutputStream 用来写出基本数据类型的数据,以下代码是数据流在文件中的使用示例:( DataOutputStreamTest.java)

package FileStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class DataOutputStreamTest {
public static void main(String[] args) {
DataOutputStream dos=null;
try {
//创建连接到指定文件的数据输出流对象
dos=new DataOutputStream(new  FileOutputStream("D:\\IOTest\\testData.dat"));
dos.writeUTF("china中国"); //写入UTF字符串
dos.writeBoolean(false); //写入布尔值
dos.writeLong(123456789L);//写入长整数
System.out.println("写文件成功!");
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if (null!=dos) {
dos.close(); //关闭过滤流时,会自动关闭它包装的底层节点流
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}


运行这个程序后,在D:\\IOTest目录下会产生一个testData.dat文件,用记事本打开这个文件,显示的内容如下:



5、掌握PrintStream、PrintWriter的使用,并编写程序,实现数据的输入和输出。

PrintStream和PrintWriter都属于打印流,提供了一系列的print和println方法,可以实现将基本数据类型的数据格式转化成字符串输出。PrintStream和PrintWriter的输出操作可能不会抛出IOException异常。

(1)以下代码(PrintStreamTest.java )是演示打印流PrintStream的使用:

package FileStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
//把标准的输出改成指定的文件输出
public class PrintStreamTest {
public static void main(String[] args) {
FileOutputStream fos=null;
try {
fos=new FileOutputStream(new File("D:\\IOTest\\text.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//创建打印输出流,设置为自动刷新模式(写入换行符或字节'\n'时都会刷新输出缓冲区)
PrintStream ps=new PrintStream(fos,true);
if (ps!=null) {
//把标准输出流(控制台输出)改成文件
System.out.println(ps);
}
for (int i = 0; i <= 255; i++) { //输出ASCII字符
System.out.print((char)i);
if (i%50==0) {
System.out.println(); //换行
}
}
ps.close();
}
}


运行这个程序后,会在D:\IOTest目录下产生一个text.txt文件,文件的内容如下截图所示:



(2)PrintStream只能封装OutputStream类型的字节流,而PrintWriter既可以封装OutputStream,还能够封装Writer类型字符输出流并增强其功能。并且它提供了PrintStream的所有打印方法,这些方法也从不抛出IOException。

以下代码(PrintWriterTest.java)演示PrintWriter的用法:

package FileStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
public class PrintWriterTest {
public static void main(String[] args) {
String str="Hello ! PrintWriter!";
try {
PrintWriter pw=new PrintWriter(new FileOutputStream("D:\\IOTest\\textPrintWriter.txt"));
pw.println(str);
pw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}


运行这个程序后,会在D:\IOTest目录下产生一个textPrintWriter.txt文件,文件的内容如下截图所示:



6、掌握ObjectInputStream、ObjectOutputStream的使用,并编写程序,实现数据的输入和输出。

ObjectInputStream类是用于存储和读取基本类型数据或对象的过滤流,它最强大之处就是可以把Java中的对象写到数据源中,也能把对象从数据源中还原回来。用ObjectOutputStream类保存基本类型数据或对象的机制叫作序列化;用ObjectInputStream类读取基本数据类型或对象的机制叫作反序列化。ObjectOutputStream和ObjectInputStream不能序列化static或transient修饰的成员变量。而且需要注意:能被序列化的对象所对应的类必须实现java.io.Serializable这个标识性接口。

(1)定义一个可序列化的Student类。代码(Student.java)如下:

package FileStream;
//可序列化的Student类
public class Student  implements java.io.Serializable{
private int id;
private String name;
private transient int age; //不需要序列化的属性
public int getId() {  return id;     }
public String getName() { return name;    }
public int getAge() {    return age;    }

public Student(int id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
public String toString() {
return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}


(2)接下来创建一个学生对象,并把它序列化到一个文件(objectSeri.dat)中。

代码(SerializationTest.java)如下所示:

package FileStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
//创建一个学生对象,并把它序列化到一个文件(objectSeri.dat)中:
public class SerializationTest {
public static void main(String[] args) {
ObjectOutputStream oos=null;
try {
//创建连接到指定文件的对象输出流实例
oos=new ObjectOutputStream(new FileOutputStream("D:\\IOTest\\objectSeri.dat"));
oos.writeObject(new Student(120, "沈", 20));
//把stu对象序列化到文件中
oos.flush();//刷新输出流
System.out.println("序列化成功!!!");
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
if(null!=oos){
oos.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}


上述程序运行后,在D:\IOTest目录下产生一个objectSeri.dat文件,文件的内容如下截图所示:



(3)把指定文件中的数据反序列化回来,打印输出它的信息。代码(DeserializationTest.java)如下:

package FileStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
//把指定文件中的数据反序列化回来,打印输出它的信息。
public class DeserializationTest {
public static void main(String[] args) {
ObjectInputStream ois=null;
try {
//创建连接到指定文件的对象输入流实例
ois=new ObjectInputStream(new FileInputStream("D:\\IOTest\\objectSeri.dat"));
Student stu=(Student)ois.readObject();//读取对象
System.out.println(stu);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}finally{
try {
if (null!=ois) {
ois.close();//关闭
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}


程序的运行结果如下:



从运行结果来看,读取出来的数据中age的值丢了,这是因为它是用transient修饰的,它的值根本没序列化到文件中。

五、实验总结

  1.本次实验按时按量完成。

  2.在Java编程中,I/O系统主要负责文件的读写。在运行程序时,Java I/O程序将源磁盘、文件或网络上的数据通过输入流类的相应方法读入内存,然后通过输出流类的相应方法将处理完的数据写回目标文件、磁盘或网络资源指定的位置。I/O系统类库位于java.io包中,提供了全面的I/O接口,包括文件读写、标准设备输出等。Java中I/O是以流为基础进行输入输出的,所有数据被串行化写入输出流,或者从输入流读入。

  3.InputStream抽象类是表示字节输入流的所有类的超类,它以字节为单位从数据源中读取数据。

OutputStream抽象类是表示字节输出流的所有类的超类,它以字节为单位向数据源写出数据。

Reader抽象类是表示字符输入流的所有类的超类,它以字符为单位从数据源中读取数据。

Writer抽象类是表示字符输出流的所有类的超类,它以字符为单位向数据源写出数据。

  4.FileInputStream和FileOutputStream是以字节为操作单位的文件输入流和文件输出流。

FileReader和FileWriter是以字符为操作单位的文件输入流和文件输出流。

  5. BufferedInputStream和BufferedOutputStream:针对字节的缓冲输入和输出流。BufferedReader和BufferedWriter:针对字符的缓冲输入和输出流。

  6.InputStreamReader用于将字节流中读取到的字节按指定字符集解码成字符。OutputStreamWriter用于将要写入到字节流中的字符按指定字符集编码成字节。

  7.DataOutputStream对输出管道进行套接,然后把一些Java类型的数据写到字节数组中去。DataInputStream对输入管道进行套接,然后可以获取相关的数据内容。

  8.PrintStream和PrintWriter都属于打印流,提供了一系列的print和println方法,可以实现将基本数据类型的数据格式转化成字符串输出。PrintStream和PrintWriter的输出操作可能不会抛出IOException异常。

9.ObjectInputStream类是用于存储和读取基本类型数据或对象的过滤流,它最强大之处就是可以把Java中的对象写到数据源中,也能把对象从数据源中还原回来。用ObjectOutputStream类保存基本类型数据或对象的机制叫作序列化;用ObjectInputStream类读取基本数据类型或对象的机制叫作反序列化。ObjectOutputStream和ObjectInputStream不能序列化static或transient修饰的成员变量。而且,能被序列化的对象所对应的类必须实现java.io.Serializable这个标识性接口。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: