标准输入、输出流与对象流,RandomAccessFile类

本文介绍了Java中的标准输入输出流,包括通过System.in和System.out实现的键盘显示器交互,以及PrintStream和PrintWriter类的功能。接着讲解了对象流的概念,涉及对象的序列化和反序列化,以及如何使用ObjectInputStream和ObjectOutputStream。同时指出序列化对象需实现Serializable接口,避免序列化问题的方法。最后讨论了RandomAccessFile类,强调其在处理数据记录文件时的读写功能和相对定位特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

标准输入输出流   

  Java中的标准输入 / 输出分别通过System.in和System.out实现,默认情况下是键盘和显示器

  PrintStream类:PrintStream为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。

  PrintWriter类:向文本输出流打印对象的格式化表示形式。此类实现在 PrintStream中的所有 print方法。它不包含用于写入原始字节的方法。

输入重定向

public class InputStreamDemo {
	public static void main(String[] args) throws FileNotFoundException {
		FileInputStream inputStream = new FileInputStream(new File("test33.txt"));
		
		//setIn
		System.setIn(inputStream);
		
		//System.out.println("请输入内容:");
		
		//默认情况下是从控制台进行获取内容
		//但是如果使用setIn方法设置了重定向之后,将从指定文件中获取内容,就不会让你再从键盘输入了
		Scanner sc = new Scanner(System.in);
		
		String string = sc.next();
		
		System.out.println(string);
	}
}

输出重定向

public class PrintStreamDemo {
	public static void main(String[] args) throws FileNotFoundException {
		//System.out.println("hello world");
		//创建打印流的对象
		//注意:默认打印到控制台,但是,如果采用setOut方法进行重定向之后,将输出到指定的文件中
		PrintStream print = new PrintStream(new FileOutputStream(new File("test33.txt")));
		/*
		 * static void setErr(PrintStream err) 
          	重新分配“标准”错误输出流。 
		static void setIn(InputStream in) 
          	重新分配“标准”输入流。 
		static void setOut(PrintStream out) 
          	重新分配“标准”输出流。 
		 * */
		//将标准输出重定向到print的输出流
		System.setOut(print);
		
		System.out.println("hello world");
	}
}

对象流

在流中流动的数据是对象
  将一个对象写入到本地文件中,称为对象的序列化
  将一个本地文件中的对象读取出来,称为对象的反序列化

如何使用对象流
  ObjectInputStream: 对象输入流
  ObjectOutputStream:对象输流

注意:
  序列化的对象必须实现Serializable接口,否则不能被序列化
  如果将多个对象序列化到本地,可以使用集合(将多个对象添加到集合中,将集合的对象写入到本地文件中,再次读出来,获取到的仍然是集合对象,遍历集合,就可以拿到对象)

对象中不可被序列化的字段:
  transient(瞬变)修饰的字段
  静态的字段

当你在序列化完对象时,如果再修改了对象中的某些属性,那么在反序列化时,就会出问题,程序会认为这是两个类,解决办法:
  在要序列化类中添加字段,保证序列化和反序列化是同一个类
  private static final long serialVersionUID = 100L;

public class ObjectStreamDemo {
	public static void main(String[] args) {
		//objectOutputStreamUsage();
		objectInputStreamUsage();
	}

	// 写:将对象进行序列化
	public static void objectOutputStreamUsage() {
		//1.实例化一个Person的对象
		Person person =  new Person("张三", 10, 'B');
		
		//2.实例化一个对象输出流的对象
		try {
			ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream(new File("file/person.txt")));
		
			//3.将对象写入到流中 writeObject
			output.writeObject(person);
			
			//4.刷新
			output.flush();
		
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		finally {
			try {
				output.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	// 读:反序列化
	public static void objectInputStreamUsage() {
		//1.实例化对象输入流的对象
		try {
			ObjectInputStream input = new ObjectInputStream(new FileInputStream(new File("file/person.txt")));
		
			//2.读取  readObject
			Object object = input.readObject();
			
			//3.对象的向下转型
			if(object instanceof Person) {
				Person p = (Person)object;
				System.out.println(p);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}	

注意:在使用对象流的时候,用于初始化对象流的参数只能是字节流(将对象转换为二进制的形式,然后再把二进制写入文件)

RandomAccessFile类

RandomAccessFile是用来访问那些保存数据记录的文件的,你就可以用seek()方法来访问记录,并进行读写了。这些记录的大小不必相同;但是其大小和位置必须是可知的。但是该类仅限于操作文件

  即可以读,又可以写,但是要求比较高

区别:
  seek(int x) 相对于开始的偏移量,连续写两次,也是从第x个位置开始读取

  skipBytes(int x) 跳过的字节个数,连续写两次,相当于从第2x个位置开始读取

public class RandomAccessFileDemo {
    public static void main(String[] args) throws IOException {
        //write();
        read();
    }

    public static void write() throws IOException {
        RandomAccessFile raf = new RandomAccessFile("ran.txt", "rw");

        //写入
        raf.writeUTF("张三");
        raf.writeInt(1);
        raf.writeBoolean(true);
        raf.writeChar('a');

        raf.writeUTF("李四");
        raf.writeInt(22);
        raf.writeBoolean(true);
        raf.writeChar('x');
        //关闭
        raf.close();
        System.out.println("写入完毕");
    }

    public static void read() throws IOException {
        RandomAccessFile raf = new RandomAccessFile("ran.txt", "r");
        //设置跳过张三
        raf.seek(21);  //偏移量
        raf.seek(21);  //效果一样 每次都是从0开始

        raf.skipBytes(21);  // 跳过21个字节
        raf.skipBytes(21);   //相当于跳过了24个字节

        //读取
        String s = raf.readUTF();
        int i = raf.readInt();
        boolean b = raf.readBoolean();
        char c = raf.readChar();

        System.out.println(s + " " + i + " " + b + " " + c);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值