`

java的IO复习

 
阅读更多
复习一下 TIJ 做一下IO的笔记 把以前的笔记转到Blog上

在core java上就把IO分成了 流和文件 这两个最最基本和最根源的类型

流就是对字节的操作 文件就是对文件和目录的操作

也就是说 File是在文件系统里 在不打开文件的情况下的操作 流是对文件的内容的操作

基础 & File类

tips

' File可以是任何文件或者是文件夹

' java 是用 "/“ 来做结合字母做转义字符 因此路径要用 "//" 来分隔 File f=new File("e://**//******")

' File类有常量 separator来表示分隔符 在linux下为 "/" 在win下为"/" 这个separator是string类型的

还有一个 separatorChar是char类型的

' File.separator 表示了当前的根目录

' File(Fileparent, Stringchild)
根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。

Filedir=newFile(File.separator);
Stirngstr
="one"+File.separator+"two.txt";
Filef
=newFile(dir,str);
f.createNewFile();

' 删除方法 delete() deleteOnExit()是在程序终止的时候删除文件

' createTempFile 是在缺省的temp目录下创建 临时文件 并赋值 构造的时候可指定前缀名和后缀名

' list() 返回目录内的文件和文件夹名称的 String[]

' FileNameFilter() 文件名过滤器接口 里面有accept方法 File的list()有能力来callback 它

String的 indexOf(string s)方法 返回此字符串的索引 如果没有返回 -1

因此 过滤文件名的时候可以这么写

Filefdir=newFile(File.separator);
Strings
="lessons"+File.separator+"ssdf"+File.separator+"09";
Filef
=newFile(fdir,s);
String[]names
=f.list(newFilenameFilter()...{
publicbooleanaccept(Filedir,Stringname)...{
returnname.indexOf(".java")!=-1;
}

}
);
for(intj=0;j<names.length;j++)
System.out.println(names[j]);

也可以像TIJ 上那样写的 再写个实现了FilenamFilter的类 作为list()的参数

eg:对文件夹的操作 列出所有文件

FileTest.java

importjava.io.*;

classFileTest...{
publicstaticvoidmain(String[]args)throwsException
...{
/**//*
//Filef=newFile("1.txt");
//f.createNewFile();
//f.mkdir();//创建文件夹
//file的另一种方法,指定路径
//Filef=newFile("E:/lessons/sunxin/09/1.txt");/注意用双反斜杠
//f.createNewFile();
Filef=newFile(File.separator);//创建文件分割符,代表当前的目录所在的盘符
Strings="lessons"+File.separator+"sunxin"+File.separator+"09"+File.separator+"1.txt";
//路径的设置是一个string类型的(中间注意要加上分割符)
//file的另一个构造方法
Filef2=newFile(f,s);//在当前目录下创建
f2.createNewFile();
//f2.delete();
f2.deleteOnExit();//在程序退出的时候删除文件
Thread.sleep(13000);
*/

Filefdir
=newFile(File.separator);
Strings
="test"+File.separator+"lessons"+File.separator+"sunxin"+File.separator+"09";
Filef
=newFile(fdir,s);
//利用list方法返回的是string类的数组,但是filenamefilter是一个接口
//用匿名类
String[]names=f.list(newFilenameFilter()...{
publicbooleanaccept(Filedir,Stringname)...{
returnname.indexOf(".java")!=-1;
}

}
);
for(intj=0;j<names.length;j++)
System.out.println(names[j]);
}

}

流类

流类用不同的分法可以分为不同的类

可分为输入流和输出流

可分为 节点流和过滤流 管道流

还可以分为 字节流和字符流

最重要和最基础的类和方法

OutputStream 所有输出流&字节流的超类

提供最基本的输出方法write()和刷新输出流的方法flush() 关闭方法close()

InputStream 所有输入流&字节流的超类

提供一些基本的读入方法 read() 重定位reset()等等方法

在lang包里有一个经常用到的System里提供了两个标准的输入和输出流in和out分别是InputStream和PrintStream

一个例子 在cmd里等待输入 并在回车后打印出来

importjava.io.*;

publicclassTest
...{
publicstaticvoidmain(String[]args)throwsException
...{
inth;
while((h=System.in.read())!=-1)
...{
System.out.write(h);
}

}

}

write(int b)

将指定的字节写入此输出流。write 的常规协定是:向输出流写入一个字节。要写入的字节是参数 b 的八个低位。b 的 24 个高位将被忽略。

read()

从输入流读取下一个数据字节。返回 0255 范围内的 int 字节值。如果因已到达流末尾而没有可用的字节,则返回值 -1。在输入数据可用、检测到流的末尾或者抛出异常前,此方法一直阻塞。

这个程序在运行的时候是这样的

在命令行里输入的字符read方法会得到字符的默认编码下的int

比如输入一个w 会得到一个01110111 也就是一个字节的十六进制的77 十进制的119 然后在write的时候将这个int的低8位写入一个字节 因为使用的是PrintStream的write 所以将会使用系统默认的字符集转换并输出字符

再比如输入的是一个 "王" 得到的是 205 245 也就是二进制的 11001101 11110101 然后用字符集转换输出

我机器的系统默认字符集使用的是GBK 所以在输出的时候没有发生乱码

分类中按节点流 过滤流来分比较好 其他的类型都比较好理解

OutputStream中 有很多子类

其中FilterOutputStream及其子类都是是过滤流

其他的FileOutputStream 等是节点流 PipedOutputStream是管道流(用于线程间的通信)

FileOutputStream是对文件的流的写操作

分别举例 创建文本文件并写入数据

importjava.io.*;

classStreamTest...{
publicstaticvoidmain(String[]args)throwsException...{
FileOutputStreamf1
=newFileOutputStream("1.rmvb");
f1.write(
"http://www.rainytooo.com".getBytes());
f1.close();


}

}

用文本编辑器打开可以看到字符串

再看看几个过滤流的作用

importjava.io.*;

classStreamTest...{
publicstaticvoidmain(String[]args)throwsException...{
FileOutputStreamf1
=newFileOutputStream("1.rmvb");

BufferedOutputStreambf
=newBufferedOutputStream(f1);

bf.write(
"http://www.rainytooo.com".getBytes());

bf.flush();
bf.close();



}

}

BufferOutputStream是过滤流中的一种 用于将字节写到缓冲先 等缓冲区满才会写入到文件中

DataOutputStream将不同的java数据类型写入到流中 都转换成byte 并且从最高位开始写

importjava.io.*;

classStreamTest...{
publicstaticvoidmain(String[]args)throwsException...{
FileOutputStreamf1
=newFileOutputStream("1.rmvb");
BufferedOutputStreambf
=newBufferedOutputStream(f1);
DataOutputStreamdf
=newDataOutputStream(bf);
bytea1=1;
chara2='a';
floata3=1.3f;
inta4=1;
df.writeByte(a1);
df.writeChar(a2);
df.writeFloat(a3);
df.writeInt(a4);
df.close();
}


}

这些数据都被换成了相应的字节数据

1 byte 1个字节 对应 01

a char 2 个字节对应 00 61

1.3f float 4个字节 对应 3F A6 66 66

1 int 4个字节 对应 00 00 00 01

这个过滤的作用就很明显了

可以自己根据需要不断重组过滤流类来得到自己想要的功能的过滤流类 只要一个过滤流的构造以另一个过滤流为参数

打印流PrintStream

System里的out 就是一个打印流 有各种格式化的输出

另一个例子用来说明管道流的作用

importjava.io.*;

classProducerextendsThread...{
privatePipedOutputStreampos;
publicProducer(PipedOutputStreampos)...{
this.pos=pos;
}

publicvoidrun()...{
try
...{
pos.write(
"Hello,RainyTooo!".getBytes());
pos.close();
}
catch(Exceptione)
...{
e.printStackTrace();
}

}

}


classConsumerextendsThread...{
privatePipedInputStreampis;
publicConsumer(PipedInputStreampis)...{
this.pis=pis;
}

publicvoidrun()...{
try
...{
byte[]byt=newbyte[100];
intlen=pis.read(byt);
System.out.println(
newString(byt,0,len));
pis.close();
}
catch(Exceptione)
...{
e.printStackTrace();
}

}

}



publicclassPipedStreamTest...{
publicstaticvoidmain(String[]args)...{
PipedOutputStreampos
=newPipedOutputStream();//创建尚未连接到传送输入流的传送输出流
PipedInputStreampis=newPipedInputStream();
try
...{
pos.connect(pis);
//用管道的输出留连接输入流;
newProducer(pos).start();//启动线程;
newConsumer(pis).start();
}
catch(Exceptione)
...{
e.printStackTrace();
}

}

}

管道流之间谁连接谁都可以的

ByteArrayOutputStream是一个把字节数组当作输出流的实现 具有缓冲区 可以在构造额达时候自己设定 其中有方便的方法得到字符串和输出到文件

主要有以下三个方便的方法

byte[] toByteArray()
创建一个新分配的字节数组。
String toString()
将缓冲区的内容转换为字符串,根据平台的默认字符编码将字节转换成字符。

toString方法还有重载的

void writeTo(OutputStreamout)
将此字节数组输出流的全部内容写入到指定的输出流参数中,这与使用 out.write(buf, 0, count) 调用该输出流的 write 方法效果一样。

一个例子

importjava.io.*;

publicclassByteArrayTest
...{
publicstaticvoidmain(String[]args)throwsException
...{
ByteArrayOutputStreambos
=newByteArrayOutputStream();

Strings
="Thisisatest";
byte[]buf=s.getBytes();
bos.write(buf);
System.out.println(bos.toString());

byte[]buf2=bos.toByteArray();
for(inti=0;i<buf.length;i++)
...{
System.out.print((
char)buf2[i]);
}



FileOutputStreamf
=newFileOutputStream("testByteArray.txt");
bos.writeTo(f);
}

}

SequenceInputStream(顺序输入流)

SequenceInputStream类允许连接多个InputStream流。SequenceInputStream的构造不同于任何其他的InputStream。SequenceInputStream构造函数要么使用一对InputStream,要么用InputStream的一个Enumeration,显示如下:
SequenceInputStream(InputStream first, InputStream second)
SequenceInputStream(Enumeration streamEnum)
操作上来说,该类满足读取完第一个InputStream后转去读取第二个流的读取要求。使用Enumeration的情况下,它将继续读取所有InputStream流直到最后一个被读完。
例子
输出两个文件内容
importjava.io.*;
importjava.util.*;
classInputStreamEnumeratorimplementsEnumeration
...{
privateEnumerationfiles;
publicInputStreamEnumerator(Vectorfiles)
...{
this.files=files.elements();
}

publicbooleanhasMoreElements()
...{
returnfiles.hasMoreElements();
}

publicObjectnextElement()
...{
try
...{
returnnewFileInputStream(files.nextElement().toString());
}
catch(Exceptione)...{
returnnull;
}

}

}


classSequenceInputStreamDemo
...{
publicstaticvoidmain(Stringargs[])throwsException
...{
intc;
Vectorfiles
=newVector();
files.addElement(
"StreamTest.java");
files.addElement(
"Test.java");
InputStreamEnumeratore
=newInputStreamEnumerator(files);
InputStreaminput
=newSequenceInputStream(e);
while((c=input.read())!=-1)
...{
System.out.print((
char)c);
}

input.close();
}

}

字符流

ReaderWrite

两个抽象类 作用就是方便字符的输入和输出 子类必须实现read和close方法

Reader的子类

BufferedReader CharArrayReader FilterReader InputStreamReader PipedReader StringReader

Writer的子类

BufferedWriter CharArrayWriter FilterWriter OutputStreamWriter PipedWriter StringWriter PrintWriter

其中InputStreamReader 的子类FileReader 和 OutputStreamWriter的 子类 FileWriter提供了对文件的直接操作字符的方式

RandomAccessFile(随机访问文件类)

RandomAccessFile 包装了一个随机访问的文件。它不是派生于InputStream 和OutputStream,而是实现定义了基本输入/输出方法的DataInput和DataOutput接口。 这个类同时具有读和写的方法 还有文件指针可以方便在制定位置读和写操作
提供了文件的随机存取的功能整合
RandomAccessFile
它是一个完全独立的class,拥有大量的原生函数,它和其他的IO有本质上的差异
,允许你在文件内自由的前后移动seek()的作用是指针
public RandomAccessFile(File file,
String mode)
throws FileNotFoundException创建从中读取和向其中写入(可选)的随机存取文件流,该文件由 File 参数指定。将创建一个新的 FileDescriptor 对象来表示此文件的连接。
mode 参数指定用以打开文件的访问模式。允许的值及其含意为:


含意

"r" 以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException。
"rw" 打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。
"rws" 打开以便读取和写入,对于 "rw",还要求对文件的内容或元数据的每个更新都同步写入到基础存储设备。
"rwd" 打开以便读取和写入,对于 "rw",还要求对文件内容的每个更新都同步写入到基础存储设备。



有3种string的写入方法
writeByte(String s)没有读取的方法
writeChar(String s)
writeUTF(String s)可以记录字节的长度在前面用两个字节表示

在RandomAccessFile中
long getFilePointer()
返回此文件中的当前偏移量。

例子 :用RandomAccessFile类读写文件
importjava.io.*;

publicclassRandomAccessFileTest
...{
publicstaticvoidmain(String[]args)throwsException
...{
Studenta1
=newStudent(1,"wang",99.0);
Studenta2
=newStudent(2,"zhang",22.0);
Studenta3
=newStudent(3,"xiang",33.0);
RandomAccessFileraf
=newRandomAccessFile("students.txt","rw");
a1.writeStudents(raf);
a2.writeStudents(raf);
a3.writeStudents(raf);

Students
=newStudent();
raf.seek(
0);//将文件指针移到启始位置;
for(longi=0;i<raf.length();i=raf.getFilePointer())//返回long型的指针偏移量
...{
s.readStudents(raf);
System.out.println(s.num
+":"+s.name+":"+s.scores);
}

raf.close();
}

}



classStudent
...{
intnum;
Stringname;
doublescores;
publicStudent()...{
}

publicStudent(intnum,Stringname,doublescores)...{
this.num=num;
this.name=name;
this.scores=scores;
}

publicvoidwriteStudents(RandomAccessFileraf)throwsIOException
...{
raf.writeInt(num);
raf.writeUTF(name);
raf.writeDouble(scores);
}

publicvoidreadStudents(RandomAccessFileraf)throwsIOException
...{
num
=raf.readInt();
name
=raf.readUTF();
scores
=raf.readDouble();
}

}

对象的序列化
将一个对象转化为字节流
以便保存和还原一个对象
对象序列化必须实现Serializable或者Externalizable接口

1 当一个对象序列化的时候只保存非静态的成员变量不能保存任何成员方法和静态的成员变量

2 如果一个对象的成员变量是一个对象,那么这个对象的数据也会被保存

3 如果一个可序列化的对象包含一个不可序列化的对象的引用,那么整个序列化的操作就将失败
声明为transient时可以继续序列化
例子:
importjava.io.*;

classObjectSerialTest
...{
publicstaticvoidmain(String[]args)throwsException
...{
Employeee1
=newEmployee("zhangsan",25,3000.50);
Employeee2
=newEmployee("lisi",24,3200.40);
Employeee3
=newEmployee("wangwu",27,3800.55);

FileOutputStreamfos
=newFileOutputStream("employee.txt");
ObjectOutputStreamoos
=newObjectOutputStream(fos);
oos.writeObject(e1);
oos.writeObject(e2);
oos.writeObject(e3);
oos.close();

FileInputStreamfis
=newFileInputStream("employee.txt");
ObjectInputStreamois
=newObjectInputStream(fis);
Employeee;
for(inti=0;i<3;i++)
...{
e
=(Employee)ois.readObject();
System.out.println(e.name
+":"+e.age+":"+e.salary);
}

ois.close();
}

}


classEmployeeimplementsSerializable
...{
Stringname;
intage;
doublesalary;
transientThreadt=newThread();
publicEmployee(Stringname,intage,doublesalary)
...{
this.name=name;
this.age=age;
this.salary=salary;
}

privatevoidwriteObject(java.io.ObjectOutputStreamoos)throwsIOException
...{
oos.writeInt(age);
oos.writeUTF(name);
System.out.println(
"WriteObject");
}

privatevoidreadObject(java.io.ObjectInputStreamois)throwsIOException
...{
age
=ois.readInt();
name
=ois.readUTF();
System.out.println(
"ReadObject");
}


}

分享到:
评论

相关推荐

    Java IO复习

    NULL 博文链接:https://justsee.iteye.com/blog/1446584

    Java中文件IO流.pdf

    Java中文件IO流.pdf 学习资料 复习资料 教学资源

    Java IO期末复习||五类一接口

    Java IO五类一接口 文件操作类File、RandomAccessFile 字节输出流OutputStream、字节输入流InputStream 字符输出流Writer、字符输入流Reader 打印流、输入输出重定向 Scanner类 字符编码 序列化操作标识接口...

    Java IO.rar_java

    IO总结资料 有助于对 Java io 部分知识的复习回顾

    Java的IO.xmind

    javaIO的复习总结思维导图,javaIO的复习总结思维导图

    Java IO, NIO and NIO.2

    这是一本介绍java io以及nio相关知识的书,书中对知识的讲解通俗易懂,是学习java nio以及复习java io相关知识的必备书籍。注意:本书为英文版!!!

    java IO 流浅谈

    最近学了java IO流 是个比较绕的东西,有时候很难理清它的头绪,即使当时清楚了,过一段时间后也会忘记,因此记录下来IO流中常用的几个类,以供大家参考,及本人以后复习

    607.605.JAVA基础教程_IO流与网络编程-复习:IO流概述(607).rar

    607.605.JAVA基础教程_IO流与网络编程-复习:IO流概述(607).rar

    java复习提纲 短小精悍

    java复习提纲,内含java io、多线程、网络、异常处理等

    java期末复习第讲面向对象程序设计.pptx

    java.io----包含能提供多种输入/输出功能的类。 java.util----包含一些实用工具类,如定义系统特性、使用与日期日历相关的函数。 第8页/共41页 java期末复习第讲面向对象程序设计全文共41页,当前为第8页。 2023年5...

    Java复习笔记/Java知识点总结

    这里面由我自己总结的一些Java知识点。 同时附赠一份我学习的资料,是github上的一位大神写...总结了Java知识、IO、http、socket、redis、git、docker,设计层次比较全,大家可以下载看看,注意文档格式是markdown的。

    Java工程师面试复习指南

    JavaIO流 多线程 深入理解内部类 javac和javap Java8新特性终极指南 序列化和反序列化 继承封装多态的实现原理 集合类 Java集合类总结 Java集合详解:一文读懂ArrayList,Vector与Stack使用方法和实现原理 Java集合...

    Java编程复习代码

    大四学期复习Java基础所产生的代码笔记,着重回顾了字符串、IO、线程以及socket套接字编程,在每一分代码中都附带了自己编程时的一些认识、笔记。适合Java基础不够踏实的童鞋。

    Java 复习.xmind

    数据结构,面向对象,反射,IO流,NIO,IO多路复用,JVM,并发.....

    Java 软件开发复习提纲.pdf

    java基础复习 反射、io流

    java IO流文件详例

    io流是任何一门语言中都非常重要的技术,繁琐的课本介绍非但不能够解决问题,还会造成很多的混淆 该文件将各个io流功能放到一起呈现,方便新手对比学习,当场实践,也方便老手进行全面的复习回顾。简洁易懂、涵盖...

    Java期末重点复习(2)

    BIT-刘滨老师的Java期末重点复习Demo第二弹 与其说是复习,不如说是从头开始学hhhh 其他细节看第一辑,这次的内容主要是: ①接口类 ②泛型(类、方法) ③匿名内部类和Lambda ④Collection 关于资源的内容,主要是...

    Java复习题及答案

    import java.io.*; class TestIO { public static void main(String[] args) { try{ RandomAccessFile raf=new RandomAccessFile("test.dat","r"); int i=raf.readInt(); } catch(IOException e){System....

    《Java基础复习》—常识与入门

    突然发现自己Java基础的底子不到位,复习! 所记知识会发布在CSDN与博客网站jirath.cn 《Java基础复习》—常识与入门 一、Java语言的知识体系图 分为三部分 编程语言核心结构:变量、基本语法、分支、循环、数组 ...

    java72-java-advance.rar

    a)java.sql b) java.util c) java.math d) java.io 2.不属于java.io包中的接口的一项是(C) a)DataInput b) DataOutput c) DataInputStream d) ObjectInput 3. ByteArrayOutputStream将下列哪一项作为输出流 C a)...

Global site tag (gtag.js) - Google Analytics