博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
I/O--(下)非流结构&内存流&读档&登录校验
阅读量:551 次
发布时间:2019-03-08

本文共 18771 字,大约阅读时间需要 62 分钟。

操作流

流文件实现的登录注册校验

DAO-接口操作集

POJO-简单用户定义集

DAO.impl-接口操作实现

  • Code总体逻辑:
    • 定义操作接口:注册-登录。

    • 定义具体实现接口:注册-登录。

      操作类接口保证文件的存在性,必须将创建文件作为静态代码块实现。
      注册将user对象的Name=PassWord通过打开user.txt文件对象流写入到user.txt,考虑写入可能失败所以需要使用try…catch…finally去实现,返回boolean型。
      登录类,通过打开文件对象流,读取每一行数据,并且通过split函数获取账号=密码,与通过界面输入的值通过equals匹配,若成功,返回true。

    • 对象类:定义简单的用户对象,以及对应的成员变量和成员方法。

    • 主函数类:界面控制问题:获取选项;判断合理性;调用对应的函数即可。

    • eg:

      /*for example*/import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.File;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import java.util.Scanner;/*用户定义*/class User {		private String username;		private String password;	public User() {	}	public String getUsername() {		return username;	}	public void setUsername(String username) {		this.username = username;	}	public String getPassword() {		return password;	}	public void setPassword(String password) {		this.password = password;	}}/*操作接口定义*/interface UserDao {		public abstract boolean isLogin(String username, String password);		public abstract void regist(User user);}/*接口具体实现*/class UserDaoImpl implements UserDao {	//保证存储文件的存在.	private static File file = new File("user.txt");	static {		try {			file.createNewFile();		} catch (IOException e) {			System.out.println("创建文件失败.");			// e.printStackTrace();		}	}	@Override	public boolean isLogin(String username, String password) {		boolean flag = false;		BufferedReader br = null;		try {						br = new BufferedReader(new FileReader(file));			String line = null;			while ((line = br.readLine()) != null) {								String[] datas = line.split("=");				if (datas[0].equals(username) && datas[1].equals(password)) {					flag = true;					break;				}			}		} catch (FileNotFoundException e) {			System.out.println("用户登录找不到信息所在的文件.");			// e.printStackTrace();		} catch (IOException e) {			System.out.println("用户登录失败.");			// e.printStackTrace();		} finally {			if (br != null) {				try {					br.close();				} catch (IOException e) {					System.out.println("用户登录释放资源失败.");					// e.printStackTrace();				}			}		}		return flag;	}	@Override	public void regist(User user) {		/*		 * 数据的存储规则为:用户名=密码.		 */		BufferedWriter bw = null;		try {			bw = new BufferedWriter(new FileWriter(file, true));			bw.write(user.getUsername() + "=" + user.getPassword());			bw.newLine();			bw.flush();		} catch (IOException e) {			System.out.println("用户注册失败.");			// e.printStackTrace();		} finally {			if (bw != null) {				try {					bw.close();				} catch (IOException e) {					System.out.println("用户注册释放资源失败.");					// e.printStackTrace();				}			}		}	}}/*Game主函数*/class GuessNumber {	private GuessNumber() {	}	public static void start() {				int number = (int) (Math.random() * 100) + 1;						int count = 0;		while (true) {								Scanner sc = new Scanner(System.in);			System.out.println("请输入数据(1-100):");			int guessNumber = sc.nextInt();			count++;			// 判断			if (guessNumber > number) {				System.out.println("你猜的数据" + guessNumber + "大了.");			} else if (guessNumber < number) {				System.out.println("你猜的数据" + guessNumber + "小了.");			} else {				System.out.println("恭喜你," + count + "次就猜中了!");				break;			}		}	}}/*主函数部分*/public class InterCalc {	public static void main(String[] args) {		// 为了能够回来		while (true) {			// 欢迎界面,给出选择项			System.out.println("--------------欢迎光临--------------");			System.out.println("1 登录");			System.out.println("2 注册");			System.out.println("3 退出");			System.out.println("请输入你的选择:");						Scanner sc = new Scanner(System.in);						String choiceString = sc.nextLine();			// 多态,接口内部调用User。			UserDao ud = new UserDaoImpl();						switch (choiceString) {			case "1":				// 登录界面,请输入用户名和密码				System.out.println("--------------登录界面--------------");				System.out.println("请输入用户名:");				String username = sc.nextLine();				System.out.println("请输入密码:");				String password = sc.nextLine();								boolean flag = ud.isLogin(username, password);				if (flag) {					System.out.println("登录成功。");					System.out.println("你玩吗?y/n");					while (true) {						String resultString = sc.nextLine();						if (resultString.equalsIgnoreCase("y")) {							// 玩游戏							GuessNumber.start();							System.out.println("你还玩吗?y/n");						} else {							break;						}					}					System.out.println("谢谢使用,欢迎下次再来!");					System.exit(0);					// break; //这里写break,结束的是switch				} else {					System.out.println("用户名或者密码有误,登录失败!");				}				break;			case "2":				// 欢迎界面,请输入用户名和密码				System.out.println("--------------注册界面--------------");				System.out.println("请输入用户名:");				String newUsername = sc.nextLine();				System.out.println("请输入密码:");				String newPassword = sc.nextLine();							User user = new User();				user.setUsername(newUsername);				user.setPassword(newPassword);				ud.regist(user);				System.out.println("注册成功.");				break;			case "3":				System.out.println("欢迎下次再来!");				System.exit(0);				break;			default:				System.out.println("请重新选择正确的选项!");								break;			}		}	}}
    • 带本地文件验证次数的登录注册验证—转到文章最后。

数据操作流 - 操作基本类型数据的流

  • DataOutputStream(OutputStream out)

    创建一个新的数据输出流,以将数据写入指定的底层输出流。

    • DataInputStream

    • DataOutputStream

    • codeDemo:

      import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;/* * 数据输入流:DataInputStream * 			DataInputStream(InputStream in). * 数据输出流:DataOutputStream * 			DataOutputStream(OutputStream out).  */public class DataStream{	public static void main(String[] args) throws IOException {			write();		read();	}private static void read() throws IOException {	// DataInputStream(InputStream in)		DataInputStream dis = new DataInputStream(			new FileInputStream("dos.txt"));	// 读数据	byte b = dis.readByte();	short s = dis.readShort();	int i = dis.readInt();	long l = dis.readLong();	float f = dis.readFloat();	double d = dis.readDouble();	char c = dis.readChar();	boolean bb = dis.readBoolean();	dis.close();	System.out.println(b);	System.out.println(s);	System.out.println(i);	System.out.println(l);	System.out.println(f);	System.out.println(d);	System.out.println(c);	System.out.println(bb);}private static void write() throws IOException {	// DataOutputStream(OutputStream out)	// 创建数据输出流对象	DataOutputStream dos = new DataOutputStream(new FileOutputStream(			"dos.txt"));	// 写数据	dos.writeByte(10);	dos.writeShort(100);	dos.writeInt(1000);	dos.writeLong(10000);	dos.writeFloat(12.34F);	dos.writeDouble(12.56);	dos.writeChar('a');	dos.writeBoolean(true);		dos.close();}}

内存操作流

描述:有些时候我们操作完毕后,未必需要产生一个文件,就可以使用内存操作流。

  • ByteArrayInputStream,ByteArrayOutputStream.
  • CharArrayReader,CharArrayWriter.
  • StringReader,StringWriter.
    /*for example*/import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;/* * 内存操作流:用于处理临时存储信息的,程序结束,数据就从内存中消失,且数据的操作不需要关闭流对象。 * 字节数组: * 		ByteArrayInputStream * 		ByteArrayOutputStream * 字符数组: * 		CharArrayReader * 		CharArrayWriter * 字符串: * 		StringReader * 		StringWriter */public class ByteArrayStream{	public static void main(String[] args) throws IOException {		// 写数据		// ByteArrayOutputStream()		ByteArrayOutputStream baos = new ByteArrayOutputStream();		// 写数据		for (int x = 0; x < 10; x++) {			baos.write(("hello" + x).getBytes());		}		// 释放资源		// 通过查看源码我们知道这里什么都没做,所以根本不需要close().		// baos.close();		// public byte[] toByteArray()		byte[] bys = baos.toByteArray();		// 读数据		// ByteArrayInputStream(byte[] buf)		ByteArrayInputStream bais = new ByteArrayInputStream(bys);		int by = 0;		while ((by = bais.read()) != -1) {			System.out.print((char) by);		}		// bais.close();	}}

打印流

  • 描述:包括字节打印流,字符打印流。
  • 特点:

只操作目的地,不操作数据源,也就是说只有写函数没有读取函数。

可以操作任意类型的数据。

如果启用了自动刷新,在调用println()方法的时候,能够换行并刷新。

可以直接操作文件.

  • 直接操作文件

    文件操作流

    /*for example*//*复制文本文件*/BufferedReader br = new BufferedReader(new FileReader("a.txt"));/*启动自动刷新:包括写入,写入新行,刷新等操作。*/PrintWriter pw = new PrintWriter(new FileWriter("b.txt"),true);String line = null;while((line=br.readLine())!=null) {	pw.println(line);}pw.close();br.close();

标准输入输出流

  • System类中的两个成员变量:

    public static final InputStream in “标准”输入流。public static final PrintStream out “标准”输出流。
  • 三种键盘录入方式

    • main方法的args接收参数,很少使用。表现方式为:public static void Main(String[] args){}.
    • System.in通过BufferedReader进行包装
      BufferedReader br = new BufferedReader(new InputStreamReader());
    • Scanner
      Scanner sc = new Scanner();
  • 输出语句的原理和如何使用字符流输出数据.

    System.out.println

    System.out.println("helloworld");	//reg.		PrintStream ps = System.out;		//reg1.ps.println("helloworld");			//reg2./*System.out用字符缓冲流包装使用.*/BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));bw.write("hello");bw.newLine();bw.write("world");bw.newLine();bw.write("java");bw.newLine();bw.flush();bw.close();

随机访问流

RandomAccessFile类不属于流,是Object类的子类。

它融合了InputStream和OutputStream的功能。

支持对文件的随机访问读取和写入。

public RandomAccessFile(String name,String mode):	第一个参数是文件路径,第二个参数是操作文件的模式。		模式有四种,我们最常用的一种叫"rw",这种方式表示我既可以写数据,也可以读取数据。		mode:must be one of "r", "rw", "rws", or "rwd"
/*for example*/import java.io.IOException;import java.io.RandomAccessFile;public class RandomAccessFileDemo {	public static void main(String[] args) throws IOException {		write();		read();	}	private static void read() throws IOException {			RandomAccessFile raf = new RandomAccessFile("raf.txt", "r");		int i = raf.readInt();		System.out.print(i);				System.out.println("\t当前指针位置:" + raf.getFilePointer());		char ch = raf.readChar();		System.out.print(ch);		System.out.println("\t当前指针位置:" + raf.getFilePointer());		String s = raf.readUTF();		System.out.print(s);		System.out.println("\t当前指针位置:" + raf.getFilePointer());				String ss = raf.readUTF();		System.out.print(ss);		System.out.println("\t当前指针位置:" + raf.getFilePointer());				String sss = raf.readUTF();		System.out.print(sss);		System.out.println("\t当前指针位置:" + raf.getFilePointer());				System.out.println("------this is a dividing line------");		raf.seek(4);		ch = raf.readChar();		System.out.println(ch);	}	private static void write() throws IOException {				RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");				raf.writeInt(100);		raf.writeChar('a');		raf.writeUTF("中华");		raf.writeUTF("人民");		raf.writeUTF("共和国");		raf.close();	}}result:100	当前指针位置:4a	当前指针位置:6中华	当前指针位置:14人民	当前指针位置:22共和国	当前指针位置:33------this is a dividing line------a/* 为什么a指针4,中华为14,因为多读两个,后面的几个string就是验证这个表现的.*/

合并流

  • 简单的描述就是将把多个输入流的数据写到一个输出流中,可以作为文件的复制合并操作。

  • 构造方法:

    SequenceInputStream(InputStream s1, InputStream s2) .SequenceInputStream(Enumeration
    e).
  • 文件合并

    /*for example:两种方式实现的文件合并.*/
    /*	要求:a.txt+b.txt=c.txt*/import java.io.BufferedOutputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.SequenceInputStream;public class SequenceInputStreamDemo {	public static void main(String[] args) throws IOException {		/*SequenceInputStream(InputStream s1, InputStream s2)*/			InputStream s1 = new FileInputStream("a.txt");		InputStream s2 = new FileInputStream("b.txt");		SequenceInputStream sis = new SequenceInputStream(s1, s2);		BufferedOutputStream bos = new BufferedOutputStream(				new FileOutputStream("c.txt"));			byte[] bys = new byte[1024];		int len = 0;		while ((len = sis.read(bys)) != -1) {			bos.write(bys, 0, len);		}		bos.close();		sis.close();	}}
    /*	要求:a.txt+b.txt+c.txt=final.txt,如下:*/import java.io.BufferedOutputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.SequenceInputStream;import java.util.Enumeration;import java.util.Vector;public class SequenceInputStreamDemo2 {	public static void main(String[] args) throws IOException {				// ByteArrayStreamDemo.java,CopyFileDemo.java,DataStreamDemo.java		// SequenceInputStream(Enumeration e)				// Enumeration
    elements() Vector
    v = new Vector
    (); InputStream s1 = new FileInputStream("a.txt"); InputStream s2 = new FileInputStream("b.txt"); InputStream s3 = new FileInputStream("c.txt"); v.add(s1); v.add(s2); v.add(s3); Enumeration
    en = v.elements(); SequenceInputStream sis = new SequenceInputStream(en); BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream("final.txt")); byte[] bys = new byte[1024]; int len = 0; while ((len = sis.read(bys)) != -1) { bos.write(bys, 0, len); } bos.close(); sis.close(); }}

序列化流

描述:可以把对象写入文本文件或者在网络中传输。

serialVersionUID匹配

  • 序列化&反序列化

    • 序列化流:把对象按照流一样的方式存入文本文件或者在网络中传输。对象 – 流数据(ObjectOutputStream)。
    • 反序列化流:把文本文件中的流对象数据或者网络中的流对象数据还原成对象。流数据 – 对象ObjectInputStream)。
      使用方法:
    让要被序列化的对象所属类实现序列化接口->	接口为:Serializable->由于一般是读取之前存储的数据对象,而不是存储&读取,所以一旦对原对象进行修改后,将报错:serialVersionUID的匹配性问题->		解决办法:使用第一个选项使用默认or第二个使用动态serialVersionUID->			可能对某些对象的成员变量不需要写入,可以使用transient来修饰。 		Serializable-----该接口是一个标记接口。没有功能需要实现。
    /*for example*//*POJO--简单对象类*/import java.io.Serializable;public class Person implements Serializable {		//序列化接口,无内容的标记接口,目的是对IO格式的匹配。	private String name;	private transient int age;		public Person() {		super();	}	public Person(String name, int age) {		super();		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 + "]";	}}/*主函数类*/import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;public class ObjectStream{	public static void main(String[] args) throws IOException,			ClassNotFoundException {		write();		read();	}	/*反序列化:流->还原对象.*/	private static void read() throws IOException, ClassNotFoundException {				ObjectInputStream ois = new ObjectInputStream(new FileInputStream(				"oos.txt"));			Object obj = ois.readObject();				ois.close();		System.out.println(obj);	}	/*序列化:对象-流.*/	private static void write() throws IOException {				ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(				"oos.txt"));				Person p = new Person("Tom", 3 );			oos.writeObject(p);				oos.close();	}}

Properties

描述:Properties类表示一组持久的属性。 Properties可以保存到流中或从流中加载。 属性列表中的每个键及其对应的值都是一个字符串。

属性列表可以包含另一个属性列表作为其“默认值”; 如果在原始属性列表中找不到属性键,则会搜索此第二个属性列表。

因为Properties从继承Hashtable时, put种putAll方法可应用于Properties对象。 强烈不鼓励使用它们,因为它们允许调用者插入其键或值不是Strings 。 应该使用setProperty方法。 如果store或save方法在包含非String键或值的“受损害” Properties对象上调用,则调用将失败。 类似地,如果在包含非String密钥的“受损害” Properties对象上调用propertyNames或list方法的调用将失败。

简而言之:就是一组持久的属性Hashtable子类,键值对都是String的数集。

继承结构如下:

Properties继承结构

  • 特有or常用函数

    import java.util.Properties;import java.util.Set;/* * Properties:属性集合类,是一个可以和IO流相结合使用的集合类。 * Properties 可保存在流中或从流中加载,属性列表中每个键及其对应值都是一个字符串。  *  * 是Hashtable的子类=>是一个Map集合。 */public class PropertiesDemo {	public static void main(String[] args) {				//错误用法:Properties
    prop = new Properties
    (); Properties prop = new Properties(); prop.put("001", "hello"); prop.put("002", "world"); prop.put("003", "java"); Set
    set = prop.keySet(); for (Object key : set) { Object value = prop.get(key); System.out.println(key + "---" + value); } }}
    /*public Object setProperty(String key,String value) //添加元素键值对组。public String getProperty(String key)	//由键获取值。public Set
    stringPropertyNames() //获取键集合,属性指定为String。*/import java.util.Properties;import java.util.Set; public class PropertiesCc { public static void main(String[] args) { Properties prop = new Properties(); prop.setProperty("Jack", "5"); prop.setProperty("Tom", "2"); prop.setProperty("coffee", "3"); /*public Set
    stringPropertyNames():获取所有的键的集合*/ Set
    set = prop.stringPropertyNames(); for (String key : set) { String value = prop.getProperty(key); System.out.println(key + "---" + value); } }}
  • Properties&IO流

    • 把集合中的数据存储到文本文件中

      public void store(Writer writer,String comments).public void store(OutputStream out,String comments).
    • 把键值对形式的文本文件内容加载到集合中

      public void load(Reader reader).public void load(InputStream inStream).
    • Code-eg:

      import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import java.io.Reader;import java.io.Writer;import java.util.Properties;public class PropertiesCc{	public static void main(String[] args) throws IOException {		myLoad();		myStore();	}	private static void myStore() throws IOException {				Properties prop = new Properties();		prop.setProperty("Jack", "5");		prop.setProperty("Tom", "2");		prop.setProperty("coffee", "3");				/*public void store(Writer writer,String comments):把集合中的数据存储到文件。*/		Writer w = new FileWriter("Store.txt");		prop.store(w, "Tips:");		w.close();	}	private static void myLoad() throws IOException {		Properties prop = new Properties();				 /*public void load(Reader reader):把文件中的数据读取到集合中,这个文件的数据必须是键值对形式。*/						 		Reader r = new FileReader("load.txt");		prop.load(r);		r.close();		System.out.println("prop:" + prop);	}}
    • Properties&读档

      /*for example*/import java.io.File;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import java.io.Reader;import java.io.Writer;import java.util.Properties;public class PropertiesDd {	public static void main(String[] args) throws IOException {		File file = new File("count.txt");		if (!file.exists()) {			file.createNewFile();			Properties prop = new Properties();			prop.setProperty("count", "0");			Writer w = new FileWriter("count.txt");			prop.store(w, null);			w.close();		}		/*把数据加载到集合*/		Properties prop = new Properties();		Reader r = new FileReader("count.txt");		prop.load(r);		r.close();		/*已知键值对关系*/		String value = prop.getProperty("count");		int number = Integer.parseInt(value);		if (number > 3) {			System.out.println("试玩结束,请付费!");			System.exit(0);		} else {			number++;			prop.setProperty("count", String.valueOf(number));			Writer w = new FileWriter("count.txt");			prop.store(w, null);			w.close();			GuessNumber.start();		}	}}

NIO

  • JDK4出现的NIO,对以前的IO操作进行了优化,但是目前还是使用以前的IO流操作…
  • JDK7的NIO
    • Path:路径

    • Paths:通过静态方法返回一个路径。

    • Files:常用函数如下使用。

    • code–eg:

      import java.io.FileOutputStream;import java.io.IOException;import java.nio.charset.Charset;import java.nio.file.Files;import java.nio.file.Paths;import java.util.ArrayList;/* * Paths:静态方法返回一个路径. * 		public static Path get(URI uri). * Files:静态方法. * 		public static long copy(Path source,OutputStream out):复制文件 * 		public static Path write(Path path,Iterable
      lines,Charset cs,OpenOption... options) */public class NIOAa { public static void main(String[] args) throws IOException { /* public static long copy(Path source,OutputStream out)--复制文件 */ Files.copy(Paths.get("Source.java"), new FileOutputStream("Copy.java")); ArrayList
      array = new ArrayList
      (); array.add("hello"); array.add("world"); /*Windows简体中文GBK,linux使用UTF-8*/ Files.write(Paths.get("Array.txt"), array, Charset.forName("GBK")); }}

转载地址:http://xewiz.baihongyu.com/

你可能感兴趣的文章