IO基础之Properties类、数据流、RandomAccessFile类、管道流和nio的简单说明

配置文件(Properties类):资源文件(以.properties作为拓展名的文件)/属性文件:
做项目开发,为何要使用配置文件?
把所有的数据存储在代码中,写死了,这叫硬编码!
比如:Java中需要连接数据库,必须拥有数据库的账号和密码;
此时我们就得在Java代码中编写,类似代码:
String username = "root";
String password = "admin";


但是,以后我们把项目部署在别人电脑/或者服务器中,别人电脑中的数据库的账号和密码可以不再是root和admin,此时部署我们就得去项目中到处去找使用了账号和密码的地方。部署项目的可能是实施人员,为了安全操作,不能让其直接修改代码。
此时,我们专门为数据库提供一个配置文件,里面专门存储数据库连接相关的信息。

db.properties

#key=value
username=root
password=admin
......


现在数据库的连接信息在db.properties文件中,而Java代码需要获取该文件中的信息:
重心转移:Java代码如何加载properties文件,如何获取该文件中的数据。
必须使用Properties类(Hashtable的子类,Map接口的实现类)。

事先准备一个文件:


读取配置文件的操作:

/**
 * Created by Layne_Yao on 2017-8-1 上午10:31:18.
 * CSDN:http://blog.csdn.net/Jsagacity
 */
public class LoadResourceDemo {

	public static void main(String[] args) throws Exception {
		//创建Properties对象
		Properties p = new Properties(); 
		//在真正开发中不宜用绝对路径:D:/Eclipse/workspace/IO/src/db.properties
		InputStream in = new FileInputStream("D:/Eclipse/workspace/IO/src/db.properties");
		//加载输入流中的数据,架在你之后,数据都在p中对象中
		p.load(in);
		
		System.out.println(p);
		System.out.println("账号:"+p.getProperty("username"));
		System.out.println("密码:"+p.getProperty("password"));
	}

}

运行结果:



加载资源文件路径:(db.properties)
注意:加载properties文件,只能使用Properties类的load方法。
方式1:
使用绝对路径的方法加载,该方式不可行。


方式2:使用相对路径-相对于classpath的根路径(字节码输出目录)(建议使用方式2)
此时得使用ClassLoader(类加载器),类加载器默认就是从classpath根路径去寻找文件的。


方式3:使用相对路径-相对于当前加载文件的字节码路径去寻找db.properties文件(注意:方式3需要把db.properties文件放在跟LoadResourceDemo.java放在一起,就是同一个目录下

代码演示:

/**
 * Created by Layne_Yao on 2017-8-3 下午2:32:40.
 * CSDN:http://blog.csdn.net/Jsagacity
 */
public class LoadResourceDemo {

	public static void main(String[] args) throws Exception {
		test1();
		test2();
		test3();
	}

	//方式3:使用相对路径-相对于当前加载资源文件的字节路径
	private static void test3() throws Exception {
		Properties p = new Properties();
		InputStream inStream = LoadResourceDemo.class.getResourceAsStream("db.properties");
		p.load(inStream);
		System.out.println(p);
		System.out.println("账号:"+p.getProperty("username"));  
        System.out.println("密码:"+p.getProperty("password"));  
	}

	//方式2:使用相对路径-相对于classpath的根路径(字节码输出目录)
	private static void test2() throws Exception {
		Properties p = new Properties();
//		ClassLoader loader = LoadResourceDemo.class.getClassLoader();
		ClassLoader loader = Thread.currentThread().getContextClassLoader();
		InputStream inStream = loader.getResourceAsStream("db.properties");
		p.load(inStream);
		System.out.println(p);
		System.out.println("账号:"+p.getProperty("username"));  
        System.out.println("密码:"+p.getProperty("password"));  
	}
	
	//方式1:使用绝对路径的方式加载
	private static void test1() throws Exception {
		Properties p = new Properties();
		InputStream inStream = new FileInputStream("D:/Eclipse/workspace/反射机制/resources/db.properties");
		p.load(inStream);
		System.out.println(p);
		System.out.println("账号:"+p.getProperty("username"));  
        System.out.println("密码:"+p.getProperty("password"));  
	}

}



数据流:(提供了可以读/写任意数据类型的方法)
DataOutputStream:
提供了writeXxx(Xxx value)方法;
DataInputStream:提供了readXxx()方法。

注意:writeXxx和readXxx必须要对应起来,比如writeByte写出的数据,此时只能使用readByte读取出来。

简单的操作:

/**
 * Created by Layne_Yao on 2017-8-1 上午10:48:10.
 * CSDN:http://blog.csdn.net/Jsagacity
 */
public class DataStreamDemo {

	public static void main(String[] args) throws Exception {
		File file = new File("file/out");
//		write(file);
		read(file);
	}

	//数据的输入
	private static void read(File file) throws Exception {
		DataInputStream in = new DataInputStream(new FileInputStream(file));
		System.out.println(in.readByte());
		System.out.println(in.readChar());
		System.out.println(in.readUTF());
		in.close();
	}

	// 数据流的输出
	private static void write(File file) throws Exception {
		DataOutputStream out = new DataOutputStream(new FileOutputStream(file));
		out.writeByte(67);
		out.writeChar('军');
		out.writeUTF("这是数据流的数据!");
		out.close();
	}

}

运行结果:






随机访问文件(RandomAccessFile类):表示可以在该文件的任何位置写出和读取数据:

简单的操作:

/**
 * Created by Layne_Yao on 2017-8-1 下午1:42:17.
 * CSDN:http://blog.csdn.net/Jsagacity
 */
public class RandomAccessFileDemo {

	public static void main(String[] args) throws Exception {
		File file = new File("file/raf.txt");
//		write(file);//先写后读
		read(file);
	}

	private static void read(File file) throws Exception {
		RandomAccessFile raf = new RandomAccessFile(file, "r");
		System.out.println("文件指针位置:"+raf.getFilePointer());
		byte b = raf.readByte();
		System.out.println(b);
		System.out.println("文件指针位置:"+raf.getFilePointer());
		String str = raf.readUTF();
		System.out.println(str);
		System.out.println("文件指针位置:"+raf.getFilePointer());
		raf.seek(2);//设置文件指针为2个字节
		System.out.println("文件指针位置:"+raf.getFilePointer());
		raf.skipBytes(19);//设置文件指针跳过19个字节
		System.out.println("文件指针位置:"+raf.getFilePointer());
		int i = raf.readInt();
		System.out.println(i);
		System.out.println("文件指针位置:"+raf.getFilePointer());
		raf.close();

	}

	private static void write(File file) throws Exception {
		RandomAccessFile raf = new RandomAccessFile(file, "rw");
		raf.writeByte(67);
		raf.writeUTF("随机访问文件");
		raf.writeInt(18);
		raf.close();
	}

}

运行结果:







管道流:实现两个线程之间的数据交互
PipedInputStream:
管道字节输入流
PipedOutputStream:管道字节输出流
PipedReder:管道字符输入流
PipedWriter:管道字符输出流


只演示字节流的代码:

/**
 * Created by Layne_Yao on 2017-8-1 下午2:07:59.
 * CSDN:http://blog.csdn.net/Jsagacity
 */
//A线程发送数据给B线程
class AThread extends Thread {
	private PipedOutputStream out = new PipedOutputStream();

	public PipedOutputStream getOut() {
		return out;
	}

	@Override
	public void run() {
		try {
			for (int i = 65; i < 91; i++) {
				out.write(i);
			}
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

//B线程接收A线程发送的数据
class BThread extends Thread{
	PipedInputStream in = null;
	public BThread(AThread aThread) throws Exception{
		in = new PipedInputStream(aThread.getOut());
	}

	@Override
	public void run() {
		int len = -1;
		try {
			while((len = in.read())!=-1){
				System.out.print((char)len);
			}
			in.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}


public class PipedStreamDemo {

	public static void main(String[] args) throws Exception {
		AThread a = new AThread();
		BThread b = new BThread(a);
		a.start();
		b.start();
	}
}

运行结果:






nio:新的IO流(new IO)
在JDK1.4开始提出的新的IO,可以吧一块磁盘文件映射到内存中,我们再去读取内存中的数据。(在java.nio包中)

Java NIO是Java1.4版本开始引入一个新的IO API,可以替代标准的Java IO API,现在主要运用于服务器中,对于我们写代码依然使用传统的IO就够了。


在JDK1.7中提取出更新的IO,叫NIO2.0!!!-->Files(文件工具类)比较常用

简单的代码演示:

/**
 * Created by Layne_Yao on 2017-8-1 下午2:43:59.
 * CSDN:http://blog.csdn.net/Jsagacity
 */
public class FilesDemo {

	public static void main(String[] args) throws Exception {
//		Files.copy(Paths.get("file/stream.txt"), new FileOutputStream("out.txt"));
		Files.copy(new FileInputStream("file/stream.txt"), Paths.get("in.txt"));
	}

}

其实我们可以查看一下底层代码的实现:


其实就是把输入流和输出流封装好给我们使用而已!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值