package com.momo.util;
import com.momo.entity.Users;
import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;
public class UserTool implements Serializable {
private ArrayList list = new ArrayList<>();
public void register() throws IOException {
try {
FileInputStream fis = new FileInputStream("users.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
list = (ArrayList)ois.readObject();
}catch (FileNotFoundException e){
System.out.println("第一次文件是空。。。");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Users u = new Users(); Scanner sc = new Scanner(System.in); Scanner sc1 = new Scanner(System.in); System.out.println("请输入你的名字:"); String s = sc.nextLine(); u.setName(s); System.out.println("请输入你的年龄:"); int age = sc1.nextInt(); u.setAge(age); System.out.println("请输入你的账户名"); String s1 = sc.nextLine(); u.setUser(s1); System.out.println("请输入你的密码:"); String s2 = sc.nextLine(); u.setPassword(s2); list.add(u); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("users.txt")); oos.writeObject(list); oos.close(); System.out.println("恭喜你注册成功!!!"); /* for (Users us : list) { System.out.println(us); }*/ } public void Input() throws IOException, ClassNotFoundException { ObjectInputStream ois = new ObjectInputStream(new FileInputStream("users.txt")); list = (ArrayList<Users>) ois.readObject(); /* for (Users us : list) { System.out.println(us); }*/ Scanner sc = new Scanner(System.in); System.out.println("请输入账户名:"); String user = sc.nextLine(); System.out.println("请输入密码:"); String password =sc.nextLine(); for (Users uu : list) { if(uu.getUser().equals(user)&&uu.getPassword().equals(password)){ System.out.println("恭喜你登录成功!!!"); } } }
}
package com.momo.demo;
import com.momo.util.UserTool;
import java.io.IOException;
import java.util.Scanner;
public class Demo1 { public static void main(String[] args) throws IOException, ClassNotFoundException { Scanner sc = new Scanner(System.in); UserTool u = new UserTool(); aa: while(true) { System.out.println("请选择你要进行的操作:1--注册 2--登录 3--退出"); int i = sc.nextInt(); switch (i) { case 1: u.register(); break; case 2: u.Input(); break; case 3 : break aa; default: System.out.println("输入有误"); } } } }
1,多线程小结:
-进程?多进程意义?
-线程?多线程意义?
-多线程的实现方式一:继承Thread,重写run
启动线程是start方法
run方法是用来包裹需要被多线程执行的代码
Thread类中操作线程的方法
-多线程实现方式二:实现Runnable接口,重写run
优点:
-使用多线程模拟卖票,引出了线程安全问题
0票的负票
某一张被卖多次
-解决方案:同步机制
同步代码块
同步方法
-生产者和消费者
如果是生产者先获取了执行权,会不断生产
如果是消费者先获取了执行权,会不断消费。
引出了,等待唤醒机制
-为什么方法在Object中?
-线程组
-线程池
多线程实现方式三,实现Callable接口
-Timer和TimerTask
1,Files
-概述
该类只包含对文件,目录或其他类型文件进行操作的静态方法。
static long copy(Path source, OutputStream out)
将文件中的所有字节复制到输出流。
static Path write(Path path, Iterable lines, OpenOption... options)
将文本行写入文件。
package com.momo.demo;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Iterator;
/*
Files是操作File的工具类
Paths是操作Path的工具类
File和Path是可以相互转换
- Files类中的方法
- */
public class Demo2 {
public static void main(String[] args) throws IOException {
long l = Files.copy(Paths.get("笔记.txt"), new FileOutputStream("aaa.txt"));
System.out.println(l);
Path p = Files.copy(Paths.get("笔记.txt"), Paths.get("bbb.txt"), StandardCopyOption.REPLACE_EXISTING); System.out.println(p); ArrayList<String> list = new ArrayList<>(); list.add("小龙"); list.add("sdfd"); list.add("sdfsd"); Path pp = Files.write(Paths.get("code.txt"), list, Charset.forName("utf8")); System.out.println(pp);
}
}
一,NIO
1,概述
-可以理解是新io,new io。
-全称java non-blocking IO 非阻塞式io
-用来替代老io的,它和老io有一样的作用
-使用方式上有很多区别
-nio面向缓冲区的,基于通道的io操作。
-使用nio可以更加高效的进行读写操作。
2,主要区别
-io:面向流, 阻塞式
-nio:面向缓冲区,非阻塞式, 选择器
3,通道和缓冲区
-java nio主要核心在于:通道(Channel) 和 缓冲区(Buffer)
-通道表示io设备的链接,要使用nio需要获取链接通道和用于
存取数据的缓冲区。然后操作缓冲区,对数据进行处理。
-简单的说:通道负责传输,缓冲区负责存取
4,缓冲区(Buffer)
-用于特定原始类型的数据的容器。 是一个抽象类
-所有的具体的缓冲区都是Buffer的子类。
-主要和nio通道交互,可以读,可以写。
package com.momo.demo;
import org.junit.Test;
import java.nio.ByteBuffer;
/*
- Buffer缓冲区:nio中负责数据存取
- 根据数据类型的不同,提供了对应的子类。(除了boolean)
- ByteBuffer , CharBuffer , DoubleBuffer , FloatBuffer , IntBuffer , LongBuffer , ShortBuffer
都可以使用allocate方法,获取对象。
缓冲区中的存取数据的方法:
- get() 从缓冲区中获取数据
- put() 给缓冲区冲存入数据 flip() 切换模式
缓冲区中的核心属性:
- capacity :容量 表示缓冲区最大可以存储的数量。一旦声明就不能改变。
- limit: 界限 表示缓冲区中现在可操作的大小。 界限之后数据不能读写。
- position: 位置 表示缓冲区中当前正在操作的位置
- mark: 标记 记录当前position位置, 使用reset恢复到mark的位置。
- */
public class Demo3 {
@Test
public void test2(){
String s = "world";
ByteBuffer buf = ByteBuffer.allocate(1024);
buf.put(s.getBytes());
buf.flip();
byte[] bys = new byte[buf.limit()];
buf.get(bys,0,2);
System.out.println(new String(bys,0,2));
System.out.println(buf.position());
buf.mark();//使用标记记录当前位置 //buf.clear(); buf.get(bys,2,2); System.out.println(new String(bys,2,2)); System.out.println(buf.position()); buf.reset();//恢复到标记位置 System.out.println(buf.position()); System.out.println("---------------"); boolean boo = buf.hasRemaining();//判断缓冲区中是否还有剩余数据 int i = buf.remaining();//获取剩余数据的数量 System.out.println(boo); System.out.println(i);
}
@Test
public void test1(){
//创建一个缓冲区
/* ByteBuffer buf = ByteBuffer.allocate(1024);
System.out.println(buf.capacity());
System.out.println(buf.limit());
System.out.println(buf.position());//
System.out.println(buf);
System.out.println(buf1);
System.out.println(buf==buf1);//
byte b = buf.get();
System.out.println(b);*/
ByteBuffer buf = ByteBuffer.allocate(1024); System.out.println(buf.capacity()); System.out.println(buf.limit()); System.out.println(buf.position()); System.out.println("--------------"); String s = "hello"; buf.put(s.getBytes()); System.out.println(buf.capacity()); System.out.println(buf.limit()); System.out.println(buf.position()); System.out.println("--------------"); //切换模式 buf.flip(); System.out.println(buf.capacity()); System.out.println(buf.limit()); System.out.println(buf.position()); System.out.println("--------------"); byte[] bys = new byte[buf.limit()]; ByteBuffer bb = buf.get(bys); System.out.println(new String(bys,0,bys.length)); System.out.println("--------------"); System.out.println(buf.capacity()); System.out.println(buf.limit()); System.out.println(buf.position()); System.out.println("--------------"); buf.rewind();//倒带这个缓冲区。 位置设置为零,标记被丢弃。 System.out.println(buf.capacity()); System.out.println(buf.limit()); System.out.println(buf.position()); System.out.println("--------------"); byte[] bys2 = new byte[buf.limit()]; buf.get(bys2); System.out.println(new String(bys2,0,bys2.length)); System.out.println("--------------"); buf.clear(); //清空缓冲区 重置缓冲区 数据还在,只是被遗忘了。 System.out.println(buf.capacity()); System.out.println(buf.limit()); System.out.println(buf.position()); System.out.println("--------------"); System.out.println((char)buf.get());
}
}
5,直接缓冲区和非直接缓冲区:
-直接缓冲区:allocateDirect方法获取的缓冲区。 把缓冲区建立在物理内存中
-非直接缓冲区:allocate方法获取的缓冲区。把缓冲区建立在jvm内存中。
-看图理解
package com.momo.demo;
import org.junit.Test;
import java.nio.ByteBuffer;
public class Demo4 { @Test public void test1(){ //获取直接缓冲区 ByteBuffer buf = ByteBuffer.allocateDirect(1024); System.out.println(buf.isDirect()); //非直接缓冲区 ByteBuffer buf2 = ByteBuffer.allocate(1024); System.out.println(buf2.isDirect()); } }
二,通道
1,通道(Channel):在Java.nio.channels包下
-表示io设备的链接。
-Channel本身不能直接访问数据,只能和Buffer进行交互。
package com.momo.demo;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
/*
- 通道Channel: 接口
- 主要实现类:
- FileChannel
- SocketChannel
- ServerSocketChannel
- DatagramChannel
- 如何获取通道?
- java本身对支持通道的类都提供了getChannel() 方法
- 本地:
- FileInputStream
- FileOutputStream
- 网络:
- Socket
- ServetSocket
- DatagramSocket
- 从jdk1.7之后 针对各个通道提供了静态的 open方法
- 在Files工具类中也有 newByteChannel()
- */
//利用通道复制文件
public class Demo5 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("111.jpg");
FileOutputStream fos = new FileOutputStream("123.jpg");
//获取通道 FileChannel inchannel = fis.getChannel(); FileChannel outchannel = fos.getChannel(); //创建缓冲区 ByteBuffer buf = ByteBuffer.allocate(1024); //把数据放入通道中的缓冲区 while (inchannel.read(buf)!=-1){ buf.flip(); outchannel.write(buf); buf.clear(); } //释放资源 fis.close(); fos.close(); inchannel.close(); outchannel.close();
}
}
package com.momo.demo;
import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
//使用直接缓冲区和open方法获取通道
/*
- static FileChannel open(Path path, OpenOption... options)
打开或创建文件,返回文件通道以访问该文件。
- StandardOpenOption 这个是OpenOption的具体子类
打开方式,在这个子类中有标准选项。
- */
public class Demo6 {
public static void main(String[] args) throws IOException {
FileChannel inchannel = FileChannel.open(Paths.get("123.jpg"), StandardOpenOption.READ);
FileChannel outchannel = FileChannel.open(Paths.get("456.jpg"), StandardOpenOption.READ,StandardOpenOption.WRITE, StandardOpenOption.CREATE);
//内存映射方式。
MappedByteBuffer inmap = inchannel.map(FileChannel.MapMode.READ_ONLY, 0, inchannel.size());
MappedByteBuffer outmap = outchannel.map(FileChannel.MapMode.READ_WRITE, 0, inchannel.size());
//读写
byte[] bys = new byte[inmap.limit()];
inmap.get(bys);
outmap.put(bys);
inchannel.close(); outchannel.close();
}
}
package com.momo.demo;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
/*
long transferFrom(ReadableByteChannel src, long position, long count)
从给定的可读字节通道将字节传输到该通道的文件中。
long transferTo(long position, long count, WritableByteChannel target)
将该通道文件的字节传输到给定的可写字节通道。
- */
public class Demo7 {
public static void main(String[] args) throws IOException {
FileChannel inchannel = FileChannel.open(Paths.get("123.mp3"), StandardOpenOption.READ);
FileChannel outchannel = FileChannel.open(Paths.get("456.mp3"), StandardOpenOption.READ,StandardOpenOption.WRITE,StandardOpenOption.CREATE);
// outchannel.transferFrom(inchannel,0,inchannel.size()); inchannel.transferTo(0,inchannel.size(),outchannel); inchannel.close(); outchannel.close();
}
}
三,分散读取和聚集写入
1,分散读取(Scattering Reads):
是指从 Channel 中读取的数据“分散”到多个 Buffer 中。
2,聚集写入(Gathering Writes)
是指将多个 Buffer 中的数据“聚集”到 Channel。
package com.momo.demo;
import org.junit.Test;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
/*
- 分散读取和聚集写入
- */
public class Demo8 {
//分散读取
@Test
public void test1() throws IOException {
RandomAccessFile raf = new RandomAccessFile("a.txt","rw");
FileChannel channel = raf.getChannel();
// FileChannel channel = FileChannel.open(Paths.get("a.txt"), StandardOpenOption.READ, StandardOpenOption.WRITE); ByteBuffer buf1 = ByteBuffer.allocate(3); ByteBuffer buf2 = ByteBuffer.allocate(3); ByteBuffer buf3 = ByteBuffer.allocate(10); ByteBuffer[] bus = {buf1,buf2,buf3}; channel.read(bus); for (ByteBuffer bb : bus) { bb.flip(); System.out.println(new String(bb.array(),0,bb.limit())); } System.out.println("--------------------------------"); //聚集写入 RandomAccessFile raf2 = new RandomAccessFile("b.txt","rw"); FileChannel channel2 = raf2.getChannel(); channel2.write(bus);
}
}