IO流7、IO流_标准的输入输出流、打印流、数据流
其他流的使用
- 标准的输入流、输出流
- 打印流
- 数据流
一、标准的输入流、输出流
-
System.in:标准的输入流,默认从键盘输入
System.out:标准的输出流,默认从控制台输出
-
System类的setIn(InputStream is) / setOut(PrintStream ps)方式重新指定输入和输出的流
/*
从键盘输入字符串,要求将读取到的整行字符串转成大写输出。然后继续进行输入操作,直至当输入“e”或者“exit”时,退出程序。
方法一:使用Scanner实现,调用next()返回一个字符串
方法二:使用System.in实现 System.in ---> 转换流 ---> BufferedRead的ReadLine()
*/
public static void main(String[] args) {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(System.in));
while (true){
System.out.println("请输入字符串:");
String data = br.readLine();
if ("e".equalsIgnoreCase(data) || "exit".equalsIgnoreCase(data)){
System.out.println("程序结束!");
break;
}
String newData = data.toUpperCase();
System.out.println(newData);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
二、打印流:PrintStream 和 PrintWriter
实现将基本数据类型的数据格式转化为字符串输出
/*
打印流
*/
@Test
public void test1(){
PrintStream ps = null;
try {
FileOutputStream fos = new FileOutputStream(new File("printStream.txt"));
// 创建打印输出流,设置为自动刷新模式(写入换行符或字节 '\n' 时都会刷新输出缓冲区)
ps = new PrintStream(fos, true);
if (ps != null) {// 把标准输出流(控制台输出)改成文件
System.setOut(ps);
}
for (int i = 0; i <= 255; i++) { // 输出ASCII字符
System.out.print((char) i);
if (i % 50 == 0) { // 每50个数据一行
System.out.println(); // 换行
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (ps != null) {
ps.close();
}
}
}
三、数据流:DataInputStream 和 DataOutputStream
操作Java语言的基本数据类型和String的数据
/*
数据流
练习:将内存中的字符串、基本数据类型的变量写出到文件中
*/
//写入
@Test
public void test2(){
DataOutputStream dos = null;
try {
dos = new DataOutputStream(new FileOutputStream("dataStream.txt"));
dos.writeUTF("张三");
dos.flush(); //刷新操作,将内存中的数据写入文件
dos.writeInt(23);
dos.flush();
dos.writeBoolean(true);
dos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (dos != null) {
try {
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/*
将文件中存储的基本数据类型变量和字符串读取到内存中,保存在变量中
注意点:读取不同类型的数据的顺序要与当初写入文件时,保存的数据顺序一致!
*/
//读取
@Test
public void test3(){
DataInputStream dis = null;
try {
dis = new DataInputStream(new FileInputStream("dataStream.txt"));
String name = dis.readUTF();
int age = dis.readInt();
boolean isMan = dis.readBoolean();
System.out.println("name = " + name);
System.out.println("age = " + age);
System.out.println("isMan = " + isMan);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (dis != null) {
try {
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
四、对象流:ObjectInputStream 和 ObjectOutputStream
作用:用于存储和读取基本数据类型数据或对象的处理流
序列化机制:允许把内存中的Java对象转换成平台无关的二进制流,从 而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传 输到另一个网络节点。
序列化:用ObjectOutputStream类保存基本类型数据或对象的机制
反序列化:用ObjectInputStream类读取基本类型数据或对象的机制
序列化过程:将内存中的java对象保存到磁盘中或通过网络传输出去,使用ObjectOutputStream实现
序列化:
//序列化!
@Test
public void testObjectOutputStream(){
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
oos.writeObject(new String("中华人民共和国!"));
oos.flush();
oos.writeObject(new Person("李四", 23));
oos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
反序列化:
//反序列化:将磁盘文件中的对象还原为内存中的一个java对象
@Test
public void testObjectInputStream(){
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("object.dat"));
Object obj = ois.readObject();
String str = (String) obj;
System.out.println(str);
Person p = (Person) ois.readObject();
System.out.println(p);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Person类
/*
Person类需要满足如下要求,才能序列化
1、需要实现接口:Serializable
2、需要当前类提供一个全局常量:serialVersionUID
3、除了当前类需要实现Serializable接口之外,还必须保证其内部所有属性也必须时可序列化的(默认情况下,基本数据类型可序列化)
*/
public class Person implements Serializable {
public static final long serialVersionUID = 3928642937452L;
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
注:ObjectInputStream 和 ObjectOutputStream不能序列化static和transient修饰的成员变量
五、随机存取文件流:RandomAccessFile
RandomAccessFile的使用
-
RandomAccessFile直接继承于Java.lang.Object类,实现了DataInput和DataOutput接口
-
RandomAccessFile既可以作为一个输出流,又可以作为输入流
-
如果RandomAccessFile作为输出流时,写出的文件如果找不到,则在执行过程中自动创建;写出的文件如果存在,则会对原有文件内容进行覆盖(默认情况下,从头覆盖)
@Test public void testRandomAccessFile(){ RandomAccessFile raf1 = null; RandomAccessFile raf2 = null; try { raf1 = new RandomAccessFile(new File("Default.jpg"), "r"); raf2 = new RandomAccessFile(new File("Default_raf.jpg"), "rw"); byte[] buffer = new byte[1024]; int len; while ((len = raf1.read(buffer)) != -1){ raf2.write(buffer, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { if (raf1 != null) { try { raf1.close(); } catch (IOException e) { e.printStackTrace(); } } if (raf2 != null) { try { raf2.close(); } catch (IOException e) { e.printStackTrace(); } } } } -
可以通过相关的操作,实现RandomAccessFile“插入”数据的效果
/* 使用RandomAccessFile实现插入效果 */ @Test public void test3(){ RandomAccessFile raf1 = null; try { raf1 = new RandomAccessFile("randomAccess.txt", "rw"); raf1.seek(22); //保存指针22后面的所有数据到StringBuilder中 StringBuilder builder = new StringBuilder((int) new File("randomAccess.txt").length()); byte[] buffer = new byte[20]; int len; while ((len = raf1.read(buffer)) != -1){ builder.append(new String(buffer, 0, len)); } //调回指针,写入数据 raf1.seek(22); raf1.write("me!".getBytes()); //将StringBuilder中的数据写入到文件中 raf1.write(builder.toString().getBytes()); } catch (IOException e) { e.printStackTrace(); } finally { if (raf1 != null) { try { raf1.close(); } catch (IOException e) { e.printStackTrace(); } } } }

浙公网安备 33010602011771号