首页 微博热点正文

超级医生,Java核心技术整理-IO,考驾照流程

一、导言

IO(输入/输出),输入是指答应程序读取外部数据(包括来自磁盘、光盘等存储设备的数据)、用户输入数据。输出是指答应程序记载运转状况,将程序数据输出到磁盘、光盘等存储设备中。

IO的首要内容包括输入、输出两种IO流,这两种流中又分为字节省和字符流,字节省是以字节为单位来处理输入、输出流,而字符流是以字符为单位来处理输入、输出流。

回到顶部

二、File 类

File 类是用来操作文件和目录的,File能创立、删去、重命名文件和目录,File不能拜访文件内容自身,File 类能够经过文件途径字符串来创立目标,创立完目标之后有许多办法来操作文件和目录:

2.1 结构办法

  • File(String pathname):依据一个途径得到File目标
  • File(String parent, String child):依据一个目录和一个子文件/目录得到File目标
  • File(File parent, String child):依据一个父File目标和一个子文件/目录得到File对

2.2 创立办法

//在当时途径来创立一个File目标
File file = new File("1.txt");
//创立文件
System.out.println(file.createNewFile());
File file2 = new File("temp");
//创立目标对应的目录
System.out.println(file2.mkdir());

2.3 重命名和删去功用

//把文件重命名为指定的文件途径
file2.renameTo(new File("temp2"));
//删去文件或许文件夹
file2.delete();

注:重命名中假如途径名相同,便是改名,假如途径名不同,便是改名并剪切。删去不走收回超级医师,Java中心技术收拾-IO,考驾照流程站,要删去一个文件夹,请注意该文件夹内不能包括文件或许文件夹。

2.4 判别功用

//判别文件或目录是否存在
System.out.println(file.exists());
//判别是否是文件
System.out.println(file.isFile());
//判别是否是目录
System.out.println(file.isDirectory());
//是否为肯定途径
System.out.println(file.isAbsolute());
//文件或目录是否可读
System.out.println(file.canRead());
//文件或目录是否可写
System.out.println(file.canWrite());

2.5 获取功用

//回来文件内容长度
System.out.println(file.length());
//获取文件或目录名
System.out.println(file.getName());
//获取文件或目录相对途径
System.out.println(file.getPath());
//获取文件或目录肯定途径
System.out.println(file.getAbsolutePath());
//获取上一级途径
System.out.println(file.getAbsoluteFile().getParent());
//回来当时目录的子目录或文件的称号
String[] list = file1.list();
for (String fileName : list) {
System.out.println(fileName);
}
//回来当时目录的子目录或文件,回来的是File数组
File[] files = file1.listFiles();
//回来体系的一切根途径
File[] listRoots = File.listRoots();
for (File root : listRoots) {
System.out.println(root);
}

回到顶部

三、IO 流

完成输大唐武侯入/输出的根底是IO流,Java把不同的源之间的数据交互笼统表达为流,经过流的办法答应Java程序运用相同的办法来拜访不同的数据源。用于操作流的类都在IO包中。

3.1 流的分类

依照不同的分类办法,流也能够分为不同类型

  1. 输入流和输出流:依据流历来分,能够分为输入流与输出流
  • 输入流:从中读取数据,而不能向其写入数据
  • 输出流:向其写入数据,而不能读取数据
  1. 字节省和字符流:这两种流用法简直彻底相同,差异在于所操作的数据单元不相同,字节省操作的数据单元是8位的字节,而字符流是16位的字符。

3.2 InputStream与Reader

InputStream和Reader是一切输入流的笼统基类,这是输入流的模板,InputStream中有三个办法

  • int read() :从输入流读取单个字节,回来所读取的字节数据。
  • int read(byte b[]):从输入流中最多读取b.length个字节的数据,并将其存储在数组b中。
  • int心爱宝物 read(byte b[], int off, int len):从输入流中最多读取len个字节的数据,并将其存储在数组b中,放入的方位是从off中开端。

Reader中也有三个办法

  • int read() :从输入流读取单个字符,回来所读取的字符数据。
  • int read(char cbuf[]):从输入流中最多读取cbuf.length个字符的数据,并将其存储在数组cbuf中。
  • int read(char cbuf[], int off, int len):从输入流中最多读取len个字符的数据,并将其存储在数组cbuf中,放入的方位是从off中开端。
  • 两个类的办法根本相同,用法相同,仅仅操作单位不相同
InputStream inputStream = new FileInputStream("StreamTest.java");
byte[] bytes = new 超级医师,Java中心技术收拾-IO,考驾照流程byte[1024];
int hasRead = 0;
while ((hasRea狗奸d = inputStream.read(bytes)) > 0) {
System.out.println(new String(bytes, 0, hasRead));
}
inputStream.close();

3.3 OutputStream与Writer

OutputStream与Writer是一切输出流的笼统基类,是输出流模板,OutputStream有三个办法:

  • void write(int b):指定字节输出到流中
  • void write(byte b[]):将指定字节数组输出到流中
  • void write(byte b[], int off, int len):将指定字节数组从off方位到len长度输出到流中

Writer中也有三个办法:

  • void write(int b):指定字符输出到流中
  • void write(char buf[]):将指定字符数组输出到流中
  • void write(char cubf[], int off, int len):将指定字符数组从off方位到len长度输出到流中

由于Writer是以字符为单位进行操作,那能够运用String 来替代,所以有别的的办法

  • void write(String str):将str字符串输出到流中
  • void write(String str, int off, int len):将str从off方位开端长度为len输出到流中
FileWriter fileWriter = new FileWriter("test辻诗音.txt");
fileWriter.write("日照香炉生紫烟\r\n");
fileWriter.write("遥看瀑布挂前川\r\n");
fileWriter.write("飞流直下三千尺\r\n");
fileWriter.write("遥看瀑布挂前川\r\n");
fileWriter.close();

注:操作流时一定要记住封闭流,由于翻开的IO资源不属于内存资源,废物收回无法收回。

四、输入/输出流体系

Java的输入输出流供给了40多个类,要悉数都记住很困难也没有必要,咱们能够依照功用进行下分类,其实对错常有规则的

一般假如输入/输出的内容是文本内容,应该考虑运用字符流,假如输入/输出内容是二进制内容,则应该考虑运用字节省。

4.1 转化流

体系中供给了两个转化流,完成将字节省转化成字符流,InputStreamReader将字节输入流通换成字符输入流,OutputStreamWriter将字节输出流通换成字符输出流,System.in代表规范输入,这个规范输入是字节输入流,可是键盘输入的都是文本内容紧身热裤,这个时分咱们能够InputStreamReader转化成字符输入流,一般的Reader读取内容不便利,咱们能够运用BufferedReader一次读取一行数据,如:

//先将System.in转化成Reader 目标
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
//再将Reader包装成BufferedReader
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String line = null;
while ((line = bufferedReader.readLine()) != null) {
if (line.equals("exit")) {
System.exit(1);
}
System.out.println("输入的内容是:" + line);
}

BufferedReader具有缓冲功用,在没有读到换行符则堵塞,读到换行符再持续。

4.2 推回输入流

推回输入流PushbackInputStream和PushbackReader中都供给超级医师,Java中心技术收拾-IO,考驾照流程了如下办法:

  • void unread(int b) :将一个字节/字符推回到推回缓冲区,然后答应重复读取刚刚读取的内容。
  • void unread(byte[] b/char[] b, int off, int len) :将一个字节/字符数组里从off开端,长度为len字节/字符的内容推回到推回缓冲区,然后答应重复读取刚刚读取的内容。
  • void unread(byte[] b/char[]):将一个字节/字符数组内容推回到推回缓冲区,然后答应重复读取刚刚读取的内容。

这两个推回流都带有一个推回缓冲区,当调用unread()办法时,体系将会把指定的内容推回到该缓冲区,而当每次调用read办法时会优先从推回缓冲区读取,只要彻底读取了推回缓冲区的内容后,但还没有read()所需的数组时才会从原输入流中读取。

 //创立PushbackReader目标,指定推回缓冲区的长度为64
PushbackReader pushbackReader = new PushbackReader(new FileReader("StreamTest.java"), 64);
char[] buf = new char[32];
//用以保存前次读取的字符串内容
String lastContent = "";
int hasRead = 0;
//循环读取文件内容
while ((hasRead = pushbackReader.read(buf)) > 0) {
//将读取的内容转化成字符串
String content = 肖宝桥new String(buf, 0, hasRead);
int targetIndex = 0;
if ((targetIndex = (lastContent + content).indexOf("new PushbackReader")) > 0) {
//将本次内容和前次的内容一同推回缓冲区
pushbackReader.unread((lastContent + content).toCharArray());
//重天佛尊新界说一个长度为targetIndex的char数组
if (targetIndex > 32) {
buf = new char[targetIndex];
}
//再次读取指定长度的内容
pushbackReader.read(buf, 0, targetIndex);
//打印读取的内容
System.out.print(new String(buf, 0, targjrr托尔金etInd脑人院ex));
System.exit(0);
} else {
//打印前次读取的内容
System.out.print(lastContent);
//将本次内容设为前次读取的内容
lastContent = content;
}
}


五、RandomAccessFile

RandomAccessFile是Java输入/输出流体系中最丰厚的文件内容拜访类,供给了许多的办法来拜访文件内容,既可读取文件内容,也能够向文件输出数据,RandomAccessFile能够自在拜访文件的恣意方位。

RandomAccessFile包括一个记载指针,用以标识当时读和写的方位,当创立新目标时,指针方位在0处,而当读/写了N个字节后,指针就会向后移动N个字节,并且RandomAccessFile能够主动的移动该指针方位,当然咱们也能够直接的获取指针的方位。

  • getFilePointer():获取文件记载指针的当时方位。
  • seek(long pos):将文件记载指针定位到pos方位。

RandomAccessFile有两个结构函数:

  • RandomAccessFile(File file, String mode):运用File文件,指定文件自身 RandomAccessFile(String name, String mode):运用文件称号,指定文件

其间还有一个参数mode(拜访形式),拜访形式有4个值:

  • r:以只读办法翻开文件
  • rw:以读、写办法翻开文件,假如文件不存在,则创立
  • rws:以读、写办法翻开文件,并要求对文件的内容或许元数据的每个更新都同步写入到底层存储设备
  • rwd:以读、写办法翻开文件,并要求对文件的内容的每个更新都同步写入到底层存储设备
RandomAccessFile raf = new RandomAccessFile("StreamTest.java", "r");
System.out.println("文件指针的初始方位:" + raf.getFilePointer());
//移动指针方位
raf.seek(300);
byte[] buf = new byte[1024];
int hasRead = 0;
while ((hasRead = raf.read(buf)) > 0) {
//读取数据
System.out.println(new String(buf, 0, hasRead));
}
//追加内容
RandomAccessFile randomAccessFile=new RandomAccessFile("out.txt","rw");
randomAccessFile.setLength(randomAccessFile.length());
randomAccessFile.write("追加的内容!\r\n".getBytes());


六、目标序列化

目标序列化机制是答应把内存中的java目标转化成渠道无关的二进制流,这样咱们能够将这二进制流保存在磁盘上或许经过网络将起传输到另一个网络节点,其他程序获取到此二进制流后,能够将其康复成本来的java目标。

要使一个目标是可序列化的,只需求承继Serializable或许Externalizable接口,无需完成任何办法。一切可能在网络上传输的目标的类都应该是可序列化的,如咱们JavaWeb中的输入参数及回来成果。

6.1 运用目标流完成序列化

咱们运用一个目标流来完成序列化目标

先建一个目标类:

@Data
public class Person implements Serializable {
private int age;
private String name;
public Person(String name, int age) {
System.out.println("有参数的结构器");
this.age = age;
this.name = name;
}
}

序列化目标与反序列化目标

//创立输出流
ObjectOutputStre48小时气候预报am objectOutputStream = new ObjectOutputStream(new FileOutputStream("object.txt"));
Person person = new Person("张三", 10);
//将person写入文件中
objectOutputStream.writeObject(person);
//创立输入流
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("object.txt"));
try {
//读出数怪物猎人epic据
Person p = (Person) objectInputStream.readObject();
System.out.println(p);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

反序列化读取的仅仅是Java目标的数据,而不java类,因而反序列化时有必要供给目标所属类的class文件,在反序列化目标时没有调用有参数的结构器,阐明反序列化时不需求经过结构器来初始化Java目标。

假如一个类中包括了引证类型,那么引证类型也有必要是可序列化的,不然该类也是不行序列化的。

假如咱们不期望某个变量被序列化,比方灵敏信息,那需求运用transient来润饰此变量即可。


七、NIO

上面学习的IO都是堵塞式的,并且是底层都是经过字节的移动来处理的,这样显着功率不高,所以后边新增了NIO来进行改善,这些类都放在java.nio包中。

新IO 是将文件或文件的一段区域映射到内存中,这样就能够像拜访内存相同来拜访文件中的内容,相当于虚拟内存概念,这种办法比传统的IO快许多。

新IO的两大中心目标是Channel(通道)与Buffer(缓冲),Channel与传统的InputStream、OutputStream最大的差异在于供给了一个map()办法,这个办法是将一块数据映射到内存中,这样新IO便是面向块进行处理;Buffer实质是一个数组,能够看做一个容器,发送到Channel中的一切目标都有必要首要放在Bu群撸ffer中,读取数据也是从Buffer中读取。

7.1 Buffer

Buffer是一个笼统类,最常用的子类是ByteChannel和CharBuffer,Buffer类都没有供给结构器,都是经过XXXBuffer allocate(int capacity) 来得到目标,如

CharBuffer allocate = CharBuffer.allocate(8);

Buffer有三个重要概念:

  • 容量(capacity):缓冲区的容量,表明该buffer的最大数据容量,即最多可存储多少数据,创立后不行改动。
  • 边界(limit):坐落limit后的数据既不能够读,也不能够写。
  • 方位(position):用于指明下一个能够被读出或写入的缓冲区方位索引,相似IO中的指针。

Buffer的首要作用是装入数据,然后输出,当创立buffer时,position在0方位,limit在capac尘世巨蟒vs北海巨妖ity,当增加数据时,position向后移动。

当Buffer装好数据时,调用flip()办法,这个办法将limit设置为position,position设置为0,也便是说不能持续输入,这就给输出数据做好预备了,而当输出数据完毕后,调用clear()办法,这是将position设置为0,limit设置为capacity,这样就为装入数据做好了预备。

除了上面的几个概念,Buffer还有两个重要办法,即put()与get()办法,便是存储与读取数据办法,在存储和读取数据时,分为相对和肯定两种:

  • 相对:从Buffer的position方位开端读取或许写入数据,这时分会改动position的数值。
  • 肯定:依据索引读取或写入数据,这个时分不会影响position的数值。
//创立buffer
CharBuffer buffer = Ch苏妤陆历承arBuffer.allocate(10);
System.out.println("capacity: " + buffer.capacity());
System.out.println("limit:" + buffer.limit());
System.out.println("position:" + buf超级医师,Java中心技术收拾-IO,考驾照流程fer.position());
//参加数据
buffer.put('a');
buffer.put('b');
buffer.put('c');
System.out.println("参加元素后,position:" + buffer.position());
buffer.flip();
System.out.println("履行flip后,limit:" + buffer.limit());
System.out.println("position:" + buffer.position());
System.out.println("取出一个数据," + buffer.get());
System.out.println("取出数据后,position:" + buffer.position());
buffer.clear();
System.out.println("履行clear后,limit:" + buffer.limit());
System.out.println(",position:" + buffer.position());
System.out.println("履行cl莱山气候ear后缓冲区未被清空:" + buffer.get(2));
System.out.println("肯定读取后,position不会改动:" + buffer.position());

7.2 Channel

Channel相似传统流目标,首要差异在于Channel能够将指定文件的部分或许悉数直接映射成Buffer,程序不能直接对Channel中的数据进行读写,只能经过Channel来进行数据读写。咱们用FileChannel来看看怎么运用:

File file = new File("StreamTest.java");
//输入流创立FileChannel
FileChannel inChannel = n超级医师,Java中心技术收拾-IO,考驾照流程ew FileInputStream(file).getChannel();
//以文件输出流创立FileChannel,操控输出
FileChannel outChannel = new FileOutputStream("a.txt").getChannel();
//将FileChannel映射成ByteBuffer,
MappedByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, file.length());
Charset charset = Charset.forName("GBK");
//输出数据
outChannel.write(buffer);
buffer.clear();
CharsetDecoder charsetDecoder = charset.newDecoder();
//转化成CharBuffer进行输出
CharBuffer charBuffer = charsetDecoder.decode(buffer);
System.out.println(charBuffer);

7.3 字符集与Charset

咱们知道,在计算机底层文件都是二进制文件,都是字节码,那为什么咱们还能看到字符,这里边触及编码和解码两个概念,简略讲,将字符转化成二进制为编码,而将二进制转成字符为解码。

Java默许运用Unicode字符集(字符集是指二进制序列与字符之间的对应联系),但许多操作体系不运用Unicode字符集,这样就会犯错,咱们要依据实际情况来运用对应的字符集。

Charset包括了创立解码器和编码器的办法,还供给了获取Charset所支撑字符集的办法,咱们能够经过Charset的forName()获取目标,经过目标获取到CharsetEncoder和CharsetDecoder目标,再经过此目标进行字符序列与字节序列的转化。

SortedMap stringChars超级医师,Java中心技术收拾-IO,考驾照流程etSortedMap = Charset.availableCharsets();
for(String name:stringCharsetSortedMap.keySet()){
System.out.println(name);
}
//创立简体中文对应的Charset
Charset cn = Charset.forName("GBK");
//创立对应的编码器及解码器
CharsetEncoder cnEncoder = cn.newEncoder();
CharsetDecoder cnDecoder = cn.newDecoder();
CharBuffer buff = CharBuffer.allocate(8);
buff.put('李');
buff.put('白');
buff.flip();
//将buff的字符转成字节序列
ByteBuffer bbuff = cnEncoder.encode(buff);
for (int i = 0; i
System.out.print(bbuff.get(i)+ " ");
}
//将bbuff的数据解码成字符
System.out.println("\n"+cnDecoder.decode(bbuff));

7.4 Path、Paths、Files

前期的Java只供给了File类来拜访文件体系,功用比较有限且功能不高,后边又供给了Path接口,Path代表一个渠道无关途径,并供给了Paths与Files两个东西类,供给了许多的办法来操作文件。

Path path = Paths.get(".");
System.out.println("path包括的文件数量:" + path.getNameCount());
System.out.println("path的根途径:" + path.getRoot());
Path path1 = path.toAbsolutePath();
System.out.println("path的肯定途径:" + path1);
//多个String构建途径
Path path2 = Paths.get("G:", "test", "codes");
System.out.println("path2的途径:" + path2);
Systproaegisem.out.println("StreamTest.java是否为躲藏文件:" + Files.isHidden(Paths.get("StreamT超级医师,Java中心技术收拾-IO,考驾照流程est.java")));
//一次性读取一切行
List allLines = Files.readAllLines(Paths.get("Str李扬达eamTest.java"), Charset.forName("gbk"));
System.out.println(allLines);
//读取巨细
System.out.println("StreamTest.java文件巨细:" + Files.size(Paths.get("StreamTest.java")));
List poem = new ArrayList<>();
poem.add("问君能有几多愁");
poem.add("恰似一江春水向东流");
//一次性写入数据
Files.write(Paths.get("poem.txt"), poem, Charset.forName("gbk"));

能够看到Paths与Files十分的强壮,供给了许多办法供咱们运用,在之前这些办法咱们自己写的话比较费事,更多的办法能够自己去看API。

7.5 文件特点

java.nio.file.attribute包下供给了许多的特点东西类,供给了很便利的办法去获取文件的特点:

BasicFileAttributeView baseView = Files.getFileAttributeView(Paths.get("poem.txt"), BasicFileAttributeView.class);
BasicFileAttributes basicFileAttributes = baseView.read简铭宣Attributes();
System.out.println("创立时刻:" + basicFileAttributes.creationTime().toMillis());
S古泰拳25式分化教育ystem.out.println("最终更新时刻:" + basicFileAttributes.lastModifiedTime().toMillis());
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。