IO流作业
一、填空题
1.Java IO流可以分为 节点流 和处理流两大类,其中前者处于IO操作的第一线,所有操作必须通过他们进行。
2.输入流的唯一目的是提供通往数据的通道,程序可以通过这个通道读取数据,read
方法给程序提供了一个从输入流中读取数据的基本方法。
3.read方法从输入流中顺序读取源中的单个字节数据,该方法返回字节值(0-255之间的一个整数),如果到达源的末尾,该方法返回 -1 。
4.Java系统的标准输入对象是System.in,标准输出对象有两个,分别是标准输出 System.out_____和标准错误输出_________System.error_________。
5.Java IO体系中,_______ObjectInputStream____________是字节输入流,不仅提供了存取所有Java基础类型数据(如:int,double 等)和String的方法,也提供了提供存取对象的方法。
6.Java IO体系中,__DataOutputStream_________________是字节输出流,提供了可以存取所有Java基础类型数据(如:int,double 等)和String的方法,但没有提供存取对象的方法。
7.___序列化_________是指将Java对象转换成字节序列,从而可以保存到磁盘上,也可以在网络上传输,使得不同的计算机可以共享对象。
二、选择题
-
使用Java IO流实现对文本文件的读写过程中,需要处理下列( B )异常。(选择一项)
A ClassNotFoundException
B. IOException
C. SQLException
D. RemoteException -
在Java的IO操作中,( D )方法可以用来刷新流的缓冲。(选择两项)
A void release()
B. void close()
C. void remove()
D. void flush() -
在Java中,下列关于读写文件的描述错误的是( B )。(选择一项)
A Reader类的read()方法用来从源中读取一个字符的数据
B. Reader类的read(int n )方法用来从源中读取一个字符的数据
C. Writer类的write(int n)方法用来向输出流写入单个字符
D. Writer类的write(String str)方法用来向输出流写入一个字符串 -
阅读下列文件定入的Java代码,共有( C )处错误。(选择一项)
import java.io.*;
public class TestIO {
public static void main(String []args){
String str =“文件写入练习”;
FileWriter fw = null; //1
try{
fw = new FileWriter(“c:\mytext.txt”); //2
fw.writerToEnd(str); //3
}catch(IOException e){ //4
e.printStackTrace();
}finally{
//此处省略关闭流
}
}
}A 0
B. 1
C. 2
D. 3 -
分析如下Java代码,有标注的四行代码中,有错误的是第( D )处。(选择一项)
import java.io.FileWriter;
import java.io.IOException;
public class Test {
public static void main(String[ ] args) {
String str = “Hello World”;
FileWriter fw = null;
try {
fw = new FileWriter(“c:\hello.txt”); // 1
fw.write(str); // 2
} catch (IOException e) {
e.printStackTrace(); // 3
} finally {
fw.close(); // 4
}
}
}A 1
B. 2
C. 3
D. 4 -
以下选项中关于如下代码的说法正确的是( AD )。(选择二项)
public class TestBuffered {
public static void main(String[] args) throws IOException {
BufferedReader br =
new BufferedReader(new FileReader(“d:/sj1.txt”));
BufferedWriter bw =
new BufferedWriter(new FileWriter(“d:/sj2.txt”));
String str = br.readLine();
while(str !=null){
bw.write(str);
bw.newLine();
str = br.readLine();
}
br.close();
bw.close();
}
}A. 该类使用字符流实现了文件复制,将d:/sj1.txt复制为d:/sj2.txt
B. FileReader和FileWriter是处理流,直接从文件读写数据
C. BufferedReader和BufferedWriter是节点流,提供缓冲区功能,提高读写效率
D. readLine()可以读取一行数据,返回值是字符串类型,简化了操作 -
InputStreamReader是转换流,可以将字节流转换成字符流,是字符流与字节流之间的桥梁。它的实现使用的设计模式是( C )。(选择一项)
A. 工厂模式
B. 装饰模式
C. 适配器模式
D. 代理模式
三、判断题
1.假设文件”a.txt”的长度为100字节,那么当正常运行语句”FileOutputStreamf=new FileOutputStream(“a.txt”);”之后,文件”a.txt”的长度变为0字节。(T)
2.ByteArrayInutStream和ByteArrayOutputStream对内存中的字节数组进行读写操作,属于字节流,属于处理流而不是节点流。 ( )
3.实现Serializable接口的可以被序列化和反序列化。该接口中没有定义抽象方法,也没有定义常量。( )
4.序列化是指将字节序列转换成Java对象,只有实现了Serializable接口的类的对象才可以被序列化。( )
四、简答题
1.输入流和输出流的联系和区别,字符流和字节流的联系和区别
答:
2.节点流和处理流的联系和区别
答:
3.列举常用的字节输入流和字节输出流并说明其特点,至少5对。
答:
4.说明缓冲流的优点和原理
答:
5.序列化的定义、实现和注意事项
答:
五、编码题
1.实现字符串和字节数组之间的相互转换。必如将字符串“数加科技sjkj”转换为字节数组,并将字节数组再转换回字符串。
2.实现字节数组和任何基本类型和引用类型执行的相互转换
提示:使用ByteArrayInutStream和ByteArrayOutputStream。
3.分别使用文件流和缓冲流复制一个长度大于100MB的视频文件,并观察效率的差异。
4.复制文件夹d:/java下面所有文件和子文件夹内容到d:/java2。
提示:涉及单个文件复制、目录的创建、递归的使用
六、可选题
1.使用IO包中的类读取D盘上exam.txt文本文件的内容,每次读取一行内容,将每行作为一个输入放入ArrayList的泛型集合中并将集合中的内容使用加强for进行输出显示。
2.假设从入学开始所有书写的Java类代码都在d:/java文件夹下,包括多级子文件夹。使用IO流获取从入学开始,到目前为止已经写了多少行Java代码。
提示:其实就是获取d:/java文件夹及其子文件夹下的所有.java文件,使用readLine()读取其中每一行,每读取一行,行数加1。所有的文件读取完毕,得到总共已经写的Java代码行数。需要结合递归实现。
由控制台按照固定格式输入学生信息,包括学号,姓名,年龄信息,当输入的内容为exit退出;将输入的学生信息分别封装到一个Student对象中,再将每个Student对象加入到一个集合中,要求集合中的元素按照年龄大小正序排序;最后遍历集合,将集合中学生信息写入到记事本,每个学生数据占单独一行。
IO流作业答案
一、填空题
1.节点流
2.read
3.-1
4.System.err
5.ObjectInputStream
6.DataOutputStream
7.序列化
二、选择题
1.B
2.D
3.B
4.C
5.D
6.AD
7.C
三、判断题
1.√
2.×
3.√
4.×
四、简答题
5.输入流和输出流的联系和区别,字符流和字节流的联系和区别
答:Java 流在处理上分为字符流和字节流。字符流处理的单元为 2 个字节的 Unicode 字符,分别操作字符、字符数组或字符串,而字节流处理单元为 1 个字节,操作字节和字节数组。输入流是将资源数据读入到缓冲Buffer中,输出流是将缓冲Buffer中的数据按照指定格式写出到一个指定的位置,所以这两个流一般同时使用,才有意义。
6.节点流和处理流的联系和区别
答:节点流表示的是直接操作节点(例如文件,键盘)的流,例如FileInputStream.
过滤流表示的是对节点流进行了操作(加工)的类,例如InputStreamReader.
7.列举常用的字节输入流和字节输出流并说明其特点,至少5对。
答:1、字节流
字节流主要是操作byte类型数据,也byte数组为准,主要操作类就是
·字节输出流:OutputStream
·字节输入流:InputStream
2、字符流
在程序中一个字符等于2个字节,那么java提供了Reader、Writer两个专门操作字符流的类。
·字符输出流:Writer
·字符输入流:Reader
3、字节-字符转换流
OutputStreamWriter和InputStreamReader
8.说明缓冲流的优点和原理
答:不带缓冲的流的工作原理:它读取到一个字节/字符,就向用户指定的路径写出去 读一个写一个 所以就慢了
带缓冲的流的工作原理:读取到一个字节/字符,先不输出,等凑足了缓冲的最大容量后一次性写出去,从而提高了工作效率
9.序列化的定义、实现和注意事项
答:在java中只要一个类实现了Serializable接口的类就被认为是序列化的类,这种类的对象就是序列化的对象
只有被序列化的数据才允许被存储到文件、数据库之中或者通过网络协议进行传输,没有被序列化的数据是不能存储到硬盘上,不能通过网络协议进行网络传输
五、编码题
1.实现字符串和字节数组之间的相互转换。必如将字符串“数加科技sjkj”转换为字节数组,并将字节数组再转换回字符串。
public class TestConvert {
public static void main(String[] args) throws IOException {
//准备一个字符串
String contents=" 近日,安徽数加科技有限公司正式成为央视网广告合作伙伴";
System.out.println(contents);
//String---byte []
byte [] buf = contents.getBytes();
//byte[]----String
String contents2 = new String(buf, 0, buf.length);
System.out.println(contents2);
}
}
2.实现字节数组和任何基本类型和引用类型执行的相互转换
提示:使用ByteArrayInutStream和ByteArrayOutputStream。
public class TestByteArrayStream {
public static void main(String[] args) throws IOException,
ClassNotFoundException {
}int num = 50;
boolean flag = true;
User user = new User("sj","sj");
//使用数据包把数据封装起来
//各种数据类型----->byte[] ByteArrayOutputStream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);//包装流
oos.writeInt(num);
oos.writeBoolean(flag);
oos.writeObject(user);
byte [] buf = baos.toByteArray();//转换为字节流
baos.close();
//byte[]----------->各种数据类型
ByteArrayInputStream bais = new ByteArrayInputStream(buf);
ObjectInputStream ois = new ObjectInputStream(bais);
int num2 = ois.readInt();
boolean flag2 = ois.readBoolean();
User user2 = (User)ois.readObject();
System.out.println(num2);
System.out.println(flag2);
System.out.println(user2);
bais.close();
}
3.分别使用文件流和缓冲流复制一个长度大于100MB的视频文件,并观察效率的差异。
public class TestCopy4 {
public static void main(String[] args) throws IOException {
//创建输入流和输出流
InputStream fis = new FileInputStream(new File("d:/1.mp4"));
OutputStream fos = new FileOutputStream("d:/2.mp4");
//使用输入流和输出流复制文件
byte [] buf = new byte[10];
int len = fis.read(buf);
while(len!=-1){
//写
fos.write(buf, 0, len);
//读
len = fis.read(buf);
//System.out.println(len);
}
//关闭输入流和输出流
fis.close();
fos.close();
}
}
public class TestCopy {
public static void main(String[] args) throws IOException {
//创建输入流和输出流
InputStream fis = new FileInputStream(new File("d:/1.mp4"));
OutputStream fos = new FileOutputStream("d:/2.mp4");
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos);
//使用输入流和输出流复制文件
byte [] buf = new byte[10];
int len = bis.read(buf);
while(len!=-1){
//写
bos.write(buf, 0, len);
//读
len = bis.read(buf);
}
//关闭输入流和输出流
bis.close();
bos.close();
}
}
4.复制文件夹d:/java下面所有文件和子文件夹内容到d:/java2。
提示:涉及单个文件复制、目录的创建、递归的使用
public class CopyDir {
/**
* 复制单个文件
* @param sourceFile 源文件
* @param targetFile 目标文件
* @throws IOException
*/
public static void copyFile(File sourceFile, File targetFile) throws IOException {
BufferedInputStream inBuff = null;
BufferedOutputStream outBuff = null;
try {
// 新建文件输入流
inBuff = new BufferedInputStream(new FileInputStream(sourceFile));
// 新建文件输出流
outBuff = new BufferedOutputStream(new FileOutputStream(targetFile));
// 缓冲数组
byte[] b = new byte[1024 * 5];
int len;
while ((len = inBuff.read(b)) != -1) {
outBuff.write(b, 0, len);
}
// 刷新此缓冲的输出流
outBuff.flush();
} finally {
// 关闭流
if (inBuff != null)
inBuff.close();
if (outBuff != null)
outBuff.close();
}
}
/**
* 复制目录
* @param sourceDir 源目录
* @param targetDir 目标目录
* @throws IOException
*/
public static void copyDirectiory(String sourceDir, String targetDir)
throws IOException {
// 检查源目录
File fSourceDir = new File(sourceDir);
if(!fSourceDir.exists() || !fSourceDir.isDirectory()){
System.out.println("源目录不存在");
return;
}
//检查目标目录,如不存在则创建
File fTargetDir = new File(targetDir);
if(!fTargetDir.exists()){
fTargetDir.mkdirs();
}
// 遍历源目录下的文件或目录
File[] file = fSourceDir.listFiles();
for (int i = 0; i < file.length; i++) {
if (file[i].isFile()) {
// 源文件
File sourceFile = file[i];
// 目标文件
File targetFile = new File(fTargetDir, file[i].getName());
copyFile(sourceFile, targetFile);
}
//递归复制子目录
if (file[i].isDirectory()) {
// 准备复制的源文件夹
String subSourceDir = sourceDir + File.separator + file[i].getName();
// 准备复制的目标文件夹
String subTargetDir = targetDir + File.separator + file[i].getName();
// 复制子目录
copyDirectiory(subSourceDir, subTargetDir);
}
}
}
public static void main(String[] args) throws IOException {
copyDirectiory("d:/java","d:/java2");
}
}
六、可选题
1.使用IO包中的类读取D盘上exam.txt文本文件的内容,每次读取一行内容,将每行作为一个输入放入ArrayList的泛型集合中并将集合中的内容使用加强for进行输出显示。
public class Test {
public static void main(String[] args) throws IOException {
String path="D:\\exam.txt";
outputMethod(path);
}
public static void outputMethod(String path) throws IOException {
List<String> list = new ArrayList<String>(); // 创建集合对象
// 创建缓冲区对象
BufferedReader br = new BufferedReader(new FileReader(path));
String line = br.readLine(); // 读取数据每次读一行
while (line != null) {
list.add(line);
line = br.readLine();
}
br.close(); //关闭
for(String s:list){
System.out.println(s);
}
}
}
2.假设从入学开始所有书写的Java类代码都在d:/java文件夹下,包括多级子文件夹。使用IO流获取从入学开始,到目前为止已经写了多少行Java代码。
提示:其实就是获取d:/java文件夹及其子文件夹下的所有.java文件,使用readLine()读取其中每一行,每读取一行,行数加1。所有的文件读取完毕,得到总共已经写的Java代码行数。需要结合递归实现。
public class TestCountDir {
private int count;
/**
* 统计一个java文件的行数
*/
private void countLine(File sourceFile) throws IOException {
BufferedReader br = null;
try {
// 新建文件输入流
br = new BufferedReader(new FileReader(sourceFile));
while(br.readLine()!=null){
count++;
//System.out.println(count);
}
} finally {
br.close();
}
}
/**
* 统计一个目录下所有Java文件的行数
*/
private void countDir(String sourceDir) throws IOException {
// 检查源目录
File fSourceDir = new File(sourceDir);
if(!fSourceDir.exists() || !fSourceDir.isDirectory()){
System.out.println("源目录不存在");
return;
}
// 遍历目录下的文件或目录
File[] file = fSourceDir.listFiles();
for (int i = 0; i < file.length; i++) {
if (file[i].isFile()) {
if(file[i].getName().toLowerCase().endsWith(".java")){
// System.out.println(file[i].getName());
countLine(file[i]);
}
}
//递归统计代码行数
if (file[i].isDirectory()) {
// 准备统计的文件夹
String subSourceDir = sourceDir + File.separator + file[i].getName();
// 统计子目录
countDir(subSourceDir);
}
}
}
public static void main(String[] args) throws IOException {
TestCountDir tcd = new TestCountDir();
tcd.countDir("d:/java");
System.out.println(tcd.count);
}
}
3.由控制台按照固定格式输入学生信息,包括学号,姓名,年龄信息,当输入的内容为exit退出;将输入的学生信息分别封装到一个Student对象中,再将每个Student对象加入到一个集合中,要求集合中的元素按照年龄大小正序排序;最后遍历集合,将集合中学生信息写入到记事本,每个学生数据占单独一行。
public class Student implements Comparable<Student>{
private Integer num;
private String name;
private Integer age;
//省略getter和setter方法
//省略构造方法
public int compareTo(Student stu) {
return this.age-stu.age;
}
public String toString() {
return "Student [age=" + age + ", name=" + name +
", num=" + num + "]";
}
}
public class Test {
public static void main(String[] args) {
Set<Student> stuSet = saveStudentInfo();
outputInfo(stuSet);
}
private static Set<Student> saveStudentInfo() {
Scanner input = new Scanner(System.in);
// 保存学生信息的TreeSet集合对象
Set<Student> stuSet = new TreeSet<Student>();
while (true) {
// 输入提示
System.out.println("请输入学生信息:(学号#姓名#年龄)");
String inputData = input.nextLine();
// 判断是否退出 inputData.equals("exit")
if ("exit".equals(inputData)) {
break;
}
// 将用户输入的学生信息分割为String[]
String[] info = inputData.split("#");
// 将输入信息封装到Student对象中
Student stu =
new Student(Integer.parseInt(info[0]), info[1],
Integer.parseInt(info[2]));
// 将学生对象加入集合
stuSet.add(stu);
}
return stuSet;
}
private static void outputInfo(Set<Student> stuSet) {
File file = new File("e:/student.txt");
// 创建文件输出流对象
FileWriter fw = null;
try {
fw = new FileWriter(file);
Iterator<Student> it = stuSet.iterator();
while (it.hasNext()) {
String info = it.next().toString();
// 将info字符串,写入记事本
fw.write(info);
// 完成换行功能
fw.write("\r\n");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}