产生文件

File file = new File("abc.txt");if(!file.exists()){

System.out.println(file.exists());

file.createNewFile();

}

System.out.println(file.getAbsolutePath());

关于临时文件

1).放在指定目录,此时已项目为默认目录

File file = File.createTempFile("defaultTmp","tmpp",new File("./"));

System.out.println(file.getAbsolutePath());

--------------------------------------------------

/Users/liuxin/work/workspace2/learnJava/./defaultTmp5487876755372558069tmpp

2).放在默认目录

File file = File.createTempFile("defaultTmp",".tmpp");

System.out.println(file.getAbsolutePath());------------------------------------------------------------------------

/var/folders/f9/x95426d95ng7wgy7f7yccj3w0000gn/T/defaultTmp1175907986750188229tmpp

3).虚拟机退出时删除临时文件

File file = File.createTempFile("defaultTmp",".tmpp");

file.deleteOnExit();

System.out.println(file.getAbsolutePath());

4).关于后缀

File testFile = new File("testFile");if(!testFile.exists()){

testFile.mkdirs();

}

testFile.deleteOnExit();

File file= File.createTempFile("defaultTmp","tmpp");

System.out.println(file.getAbsolutePath());

File file2= File.createTempFile("defaultTmp2",".tmpp",testFile);

System.out.println(file2.getAbsolutePath());

File file3= File.createTempFile("defaultTmp3",null,testFile);

System.out.println(file3.getAbsolutePath());=======================================

/var/folders/f9/x95426d95ng7wgy7f7yccj3w0000gn/T/defaultTmp5296324826431648502tmpp/Users/liuxin/work/workspace2/learnJava/testFile/defaultTmp21551336802243345058.tmpp/Users/liuxin/work/workspace2/learnJava/testFile/defaultTmp33930717872920538957.tmp

操作目录

1.查看目录下的所有文件

File currentFile = new File(".");

System.out.println(currentFile.getAbsolutePath());for(File file : currentFile.listFiles()){

System.out.println(file.getName());

}

getParent()的使用方法

File file = new File(".");

System.out.println(file.getAbsolutePath());

System.out.println(newFile(file.getAbsolutePath()).getParent());-----------------------

/Users/liuxin/work/workspace2/learnJava/./Users/liuxin/work/workspace2/learnJava

getParent()只有在定义文件时有路径时才起作用.

15.2 流

字节流主要由InputStream和OutputStream作为基类,而字符流则主要由Reader和Writer作为基类.

字节流操作的数据单元是8位的字节,而字符流操作的数据单元是16位的字符

节点流和处理流,节点流是低级流,直接跟数据源相接.处理流(也叫包装流)把节点流包装了一层,属于修饰器设计模式.

处理流的功能主要体现在以下两个方面:

1.性能的提高:主要以增加缓冲的方式来提高输入输出的效率

2.操作的便捷:处理流可能提供了一系列便捷的方法来一次输入输出大批量的内容,而不是输入/输出一个或多个水滴

处理流可以嫁接在任何已存在的流的基础上.

15.3.1 InputStream和Reader

InputStream和Reader是所有输入流的抽象基类,本身并不能创建实例来执行.

读取文件的demo

public static voidtestFile() throws IOException{//创建字节输入流

FileInputStream fis = new FileInputStream("a.txt");//创建一个长度为1024的“竹筒”

byte[] bbuf = new byte[1024];//用于保存实际读取的字节数

int hasRead = 0;//使用循环来重复“取水”过程

while ((hasRead = fis.read(bbuf)) > 0)

{//取出“竹筒”中水滴(字节),将字节数组转换成字符串输入!

System.out.print(new String(bbuf , 0, hasRead ));

}//关闭文件输入流,放在finally块里更安全

fis.close();

}

关于fileFilter

File file = new File(".");

String[] nameList= file.list((dir, name) -> name.endsWith(".java")|| newFile(name).isDirectory());for(String name : nameList)

{

System.out.println(name);

}================================.settings

a

bin

lib

result

sqlModify

src

testFile

15.2 理解java的IO流

用字节流读取文件并打印

public static voidtestFile2() throws IOException{//创建字节输入流

FileInputStream fis = new FileInputStream("a.txt");//读取一个字节,返回的是int,所以要用char强转

System.out.println((char)fis.read());//创建一个长度为1024的“竹筒”

byte[] bbuf = new byte[1024];//读取5个字节,放在bbuf的index为10的位置

fis.read(bbuf,10,10);//从bbuf中index为10的位置读取5个字节构成字符串

System.out.println(new String(bbuf , 10, 5));//转换成String后,byte[]不变

System.out.println(new String(bbuf , 10, 5));//用于保存实际读取的字节数

int hasRead = 0;//使用循环来重复“取水”过程

while ((hasRead = fis.read(bbuf)) > 0)

{//重新赋值后,byte[]会改变

System.out.println(new String(bbuf , 10, 5));//取出“竹筒”中水滴(字节),将字节数组转换成字符串输入!

System.out.println("==============================================");

String test= new String(bbuf , 0, hasRead );

System.out.println(test);

System.out.println("=================="+new String(bbuf , 0 , hasRead ).length()+"============================");

}//关闭文件输入流,放在finally块里更安全

fis.close();

}

打印结果如下

<

?xml?xml

ncodi==============================================on="1.0" encoding="UTF-8"?>

learnJava

org.eclipse.jdt.core.javabuilder

org.eclipse.jdt.core.javanature

我很好啊,看看需不要utf-8

==================373============================

public static voidtestFile3() {try(//创建字符输入流

FileReader fr = new FileReader("a.txt")

){//创建一个长度为32的“竹筒”

char[] cbuf = new char[32];

System.out.println(fr.read(cbuf,0,32));

System.out.println(newString(cbuf));//用于保存实际读取的字符数

int hasRead = 0;//使用循环来重复“取水”过程

while ((hasRead = fr.read(cbuf)) > 0)

{//取出“竹筒”中水滴(字符),将字符数组转换成字符串输入!//System.out.print(new String(cbuf , 0 , hasRead));

System.out.print(newString(cbuf));

}

}catch(IOException ex)

{

ex.printStackTrace();

}

}

outPutStream 和 Writer

public static voidtestFileWriter() {

//这里a.txt可以不存在,如果不存在回自动生成,但是没搞明白怎么设置编码格式try(FileWriter fw = new FileWriter("a.txt"))

{

fw.write("锦瑟 - 李商隐\r\n");

fw.write("锦瑟无端五十弦,一弦一柱思华年。\r\n");

fw.write("庄生晓梦迷蝴蝶,望帝春心托杜鹃。\r\n");

fw.write("沧海月明珠有泪,蓝田日暖玉生烟。\r\n");

fw.write("此情可待成追忆,只是当时已惘然。\r\n");

}catch(IOException ioe)

{

ioe.printStackTrace();

}

}

15.4 输入输出流体系

处理流:构造参数是已经存在的流.

节点流:构造参数是物理IO节点

处理流的用法

public static voidPrintStream() {try(

FileOutputStream fos= new FileOutputStream("a.txt");

PrintStream ps= newPrintStream(fos))

{//使用PrintStream执行输出

ps.println("普通字符串");//直接使用PrintStream输出对象

ps.println(newLearnIO());

}catch(IOException ioe)

{

ioe.printStackTrace();

}

}

输出结果

普通字符串

learnIO.LearnIO@677327b6

在使用了处理流包装了底层节点之后,关闭输入/输出流资源时,只要关闭最上层的处理流即可。关闭最上层的处理流时,系统会自动关闭被该处理流包装的节点流。

字符串流的用法,似乎没什么用,等发现用处再补充

public static voidstringNodeTest() {

String src= "从明天起,做一个幸福的人\n"

+ "喂马,劈柴,周游世界\n"

+ "从明天起,关心粮食和蔬菜\n"

+ "我有一所房子,面朝大海,春暖花开\n"

+ "从明天起,和每一个亲人通信\n"

+ "告诉他们我的幸福\n";char[] buffer = new char[32];int hasRead = 0;try(

StringReader sr= newStringReader(src))

{//采用循环读取的访问读取字符串

while((hasRead = sr.read(buffer)) > 0)

{

System.out.print(new String(buffer ,0, hasRead));

}

}catch(IOException ioe)

{

ioe.printStackTrace();

}try(//创建StringWriter时,实际上以一个StringBuffer作为输出节点//下面指定的20就是StringBuffer的初始长度

StringWriter sw = newStringWriter())

{//调用StringWriter的方法执行输出

sw.write("有一个美丽的新世界,\n");

sw.write("她在远方等我,\n");

sw.write("哪里有天真的孩子,\n");

sw.write("还有姑娘的酒窝\n");

System.out.println("----下面是sw的字符串节点里的内容----");//使用toString()方法返回StringWriter的字符串节点的内容

System.out.println(sw.toString());

}catch(IOException ex)

{

ex.printStackTrace();

}

}

15.4.3 转换流

InputStreamReader :将字节输入流转换成字符输入流

OutputStreamWriter:将字节输出流转换成字符输出流

经过测试,下面这个程序是有一定问题的,用输入法的时候,会重复输出好多遍

public static voidKeyinTest() {try(//将Sytem.in对象转换成Reader对象

InputStreamReader reader = new InputStreamReader(System.in);//将普通Reader包装成BufferedReader

BufferedReader br = newBufferedReader(reader))

{

String line= null;//采用循环方式来一行一行的读取

while ((line = br.readLine()) != null)

{//如果读取的字符串为"exit",程序退出

if (line.equals("exit"))

{

System.exit(1);

}//打印读取的内容

System.out.println("输入内容为:" +line);

}

}catch(IOException ioe)

{

ioe.printStackTrace();

}

}

15.4.4 推回输入流

PushbackInputStream和PushbackReader

用unread方法将内容推回到缓冲区,从而允许重复读取刚刚读取的内容.

使用推回流,输出某分割符号之前的内容。但其实完全不必这么做,读出来判断就好了。

public static voidpushbackTest() {try(//创建一个PushbackReader对象,指定推回缓冲区的长度为64

PushbackReader pr = new PushbackReader(new FileReader("a.txt") , 64))

{char[] buf = new char[32];//用以保存上次读取的字符串内容

String lastContent = "";int hasRead = 0;//循环读取文件内容

while ((hasRead = pr.read(buf)) > 0)

{//将读取的内容转换成字符串

String content = new String(buf , 0, hasRead);int targetIndex = 0;//将上次读取的字符串和本次读取的字符串拼起来,//查看是否包含目标字符串, 如果包含目标字符串

if ((targetIndex = (lastContent +content)

.indexOf("测试")) > 0)

{//将本次内容和上次内容一起推回缓冲区

pr.unread((lastContent +content).toCharArray());//重新定义一个长度为targetIndex的char数组

if(targetIndex > 32)

{

buf= new char[targetIndex];

}//再次读取指定长度的内容(就是目标字符串之前的内容)

pr.read(buf , 0, targetIndex);//打印读取的内容

System.out.print(new String(buf , 0,targetIndex));

System.exit(0);

}else{//打印上次读取的内容

System.out.print(lastContent);//将本次内容设为上次读取的内容

lastContent =content;

}

}

}catch(IOException ioe)

{

ioe.printStackTrace();

}

}

system类里提供了三个重定向标准输入输出的方法。

setErr(PrintStream err)

setIn(InputStream in)

setOut(PrintStream out)

程序可通过重定向标准输出流,将System.out的输出重定向到文件输出.

15.6 Java虚拟机读写其他进程的数据

使用Runtime对象的exec()方法可以运行平台上的其他程序,该方法产生一个Process对象,Process对象代表由该Java程序启动的子进程.Process类提供了如下三个方法,用于让程序和其子进程进行通信.

InputStream getErrorStream():获取子进程的错误流,

InputStream getInputStream(): 获取子进程的输入流.

OutputStream getOutputStream(): 获取子进程的输出流.

这里的输入流和输出流是相对于该java程序(注意,不是子程序)而言的.这里的子进程相当于物理节点

注意,这里用的是getErrorStream(),因为这不是子进程向本进程传递的数据,所以属于其他,要用ErrorStream

public static voidreadFromProcess() throws IOException {//运行javac命令,返回运行该命令的子进程

Process p = Runtime.getRuntime().exec("java -version");try(//以p进程的错误流创建BufferedReader对象//这个错误流对本程序是输入流,对p进程则是输出流

BufferedReader br = new BufferedReader(newInputStreamReader(p.getErrorStream())))

{

String buff= null;//采取循环方式来读取p进程的错误输出

while((buff = br.readLine()) != null)

{

System.out.println(buff);

}

}

}

java version "1.8.0_51"Java(TM) SE Runtime Environment (build1.8.0_51-b16)

Java HotSpot(TM)64-Bit Server VM (build 25.51-b03, mixed mode)

java两个程序之间传递信息:这端代码我没跑起来,待研究

public classWriteToProcess

{public static voidmain(String[] args)

throws IOException

{//运行java ReadStandard命令,返回运行该命令的子进程

Process p = Runtime.getRuntime().exec("java ReadStandard");try(//以p进程的输出流创建PrintStream对象//这个输出流对本程序是输出流,对p进程则是输入流

PrintStream ps = newPrintStream(p.getOutputStream()))

{//向ReadStandard程序写入内容,这些内容将被ReadStandard读取

ps.println("普通字符串");

ps.println(newWriteToProcess());

}

}

}//定义一个ReadStandard类,该类可以接受标准输入,//并将标准输入写入out.txt文件。

classReadStandard

{public static voidmain(String[] args)

{try(//使用System.in创建Scanner对象,用于获取标准输入

Scanner sc = new Scanner(System.in);

PrintStream ps= newPrintStream(new FileOutputStream("out.txt")))

{//增加下面一行将只把回车作为分隔符

sc.useDelimiter("\n");//判断是否还有下一个输入项

while(sc.hasNext())

{//输出输入项

ps.println("键盘输入的内容是:" +sc.next());

}

}catch(IOException ioe)

{

ioe.printStackTrace();

}

}

}

15.7 RandomAccessFile

RandomAccessFile可以自由访问文件的任意位置,所以如果只需要访问文件部分内容,而不是把文件从头读到尾,使用RamdomAccessFile将是更好的选择.但是局限是,它只能读写文件,不能读写其他IO节点.

getFilePointer():返回文件记录指针的当前位置

seek(long pos):将文件记录指针定位到pos位置

public static voidrandomAccessFileTest(){try(

RandomAccessFile raf= newRandomAccessFile("newFile.txt" , "r"))

{//获取RandomAccessFile对象文件指针的位置,初始位置是0

System.out.println("RandomAccessFile的文件指针的初始位置:"

+raf.getFilePointer());//移动raf的文件记录指针的位置

raf.seek(30);byte[] bbuf = new byte[1024];//用于保存实际读取的字节数

int hasRead = 0;//使用循环来重复“取水”过程

while ((hasRead = raf.read(bbuf)) > 0)

{//取出“竹筒”中水滴(字节),将字节数组转换成字符串输入!

System.out.print(new String(bbuf , 0, hasRead ));

}

}catch(IOException ex)

{

ex.printStackTrace();

}

}

RandomAccessFile 依然不能向文件的指定位置插入内容,如果直接将文件记录指针移动到中间某位置后开始输出,则新输出的内容会覆盖文件中原有的内容,如果需要向指定位置插入内容,程序需要先把插入点后面的内容读入缓冲区,等把需要插入的数据写入文件后,再将缓冲区的内容追加到文件的后面.

public static void insert(String fileName , longpos

, String insertContent) throws IOException

{

File tmp= File.createTempFile("tmp" , null);

tmp.deleteOnExit();try(

RandomAccessFile raf= new RandomAccessFile(fileName , "rw");//使用临时文件来保存插入点后的数据

FileOutputStream tmpOut = newFileOutputStream(tmp);

FileInputStream tmpIn= newFileInputStream(tmp))

{

raf.seek(pos);//------下面代码将插入点后的内容读入临时文件中保存------

byte[] bbuf = new byte[64];//用于保存实际读取的字节数

int hasRead = 0;//使用循环方式读取插入点后的数据

while ((hasRead = raf.read(bbuf)) > 0)

{//将读取的数据写入临时文件

tmpOut.write(bbuf , 0, hasRead);

}//----------下面代码插入内容----------//把文件记录指针重新定位到pos位置

raf.seek(pos);//追加需要插入的内容

raf.write(insertContent.getBytes());//追加临时文件中的内容

while ((hasRead = tmpIn.read(bbuf)) > 0)

{

raf.write(bbuf ,0, hasRead);

}

}

}

如果仅仅是追加内容,就简单多了

public static voidmain(String[] args)

{try(//以读、写方式打开一个RandomAccessFile对象

RandomAccessFile raf = new RandomAccessFile("out.txt" , "rw"))

{//将记录指针移动到out.txt文件的最后

raf.seek(raf.length());

raf.write("追加的内容!\r\n".getBytes());

}catch(IOException ex)

{

ex.printStackTrace();

}

}

15.8 对象序列化(serialize)

对象的序列化指将一个java对象写入IO流中,与此对应的是,对象的反序列化(Deserialize)则指从IO流中恢复该java对象.

如果需要让某个对象支持序列化机制,那么必须让它的类是可序列化的,必须实现如下两个接口之一

Serializable

Externalizable

程序创建的每个JavaBean类都要实现Serializable

public static voidwriteObject() {try (ObjectOutputStream oos = newObjectOutputStream(new FileOutputStream("obj.txt"));)

{

LearnIO learnIO= new LearnIO("12334444444");

oos.writeObject(learnIO);

}catch(IOException ex) {//TODO: handle exception

ex.printStackTrace();

}

}

//但是,如果如下

LearnIO learnIO = new LearnIO("12334444444");

oos.writeObject(learnIO);

learnIO.test="abcdetc";

//不会写入abcdetc,因为不会序列化号码相同的东西

oos.writeObject(learnIO);

反序列化

public static voidreadObject(){try(

ObjectInputStream ois= new ObjectInputStream(new FileInputStream("obj.txt"));

){

LearnIO learnIO=(LearnIO)ois.readObject();

System.out.println(learnIO.test);

}catch(Exception e) {//TODO: handle exception

e.printStackTrace();

}

}

反序列化机制无须通过构造器来初始化java对象.

如果使用序列化机制向文件中写入多个Java对象,使用反序列化机制恢复对象时必须按实际写入的顺序读取.

当一个可序列化类有多个父类时(包括直接父类和间接父类),这些父类要么有无参数的构造器,要么也是可序列化的--否则反序列化时将抛出InvalidClassException异常.如果父类是不可序列化的,只是带有无参数的构造器,则该父类中定义的成员变量值不会序列化到二进制流中.

15.8.3 对象引用的序列化

如果成员变量是引用类型,那么这个引用类型的类必须是可序列化的.

属于递归序列化

有static修饰和transient修饰的变量不会被序列化

15.8.4 自定义序列化

在实例变量前面使用transient关键字修饰,可以指定java序列化时无须理会该实例变量.

更详细的自定义序列化方法是重写writeObject和readObject方法.

15.8.5 另一种自定义序列化机制

实现Externalizable

java疯狂讲义3_java8--IO(java疯狂讲义3复习笔记)相关推荐

  1. java8--IO(java疯狂讲义3复习笔记)

    产生文件 File file = new File("abc.txt");if(!file.exists()){System.out.println(file.exists()); ...

  2. 《Java疯狂讲义》(第3版)学习笔记 2 - Java语言的运行机制

    内容 1.高级语言的运行机制 2.Java 语言的运行机制 1.高级语言的运行机制 高级语言主要分为编译型语言和解释型语言两类. 编译型语言是指使用专门的编译器.针对特定平台(操作系统)将高级语言源代 ...

  3. 疯狂涨知识!Java多态实现原理技术总监都拍手叫好

    ##前言 多态是Java语言重要的特性之一,它允许基类的指针或引用指向派生类的对象,而在具体访问时实现方法的动态绑定.Java对于方法调用动态绑定的实现主要依赖于方法表,但通过引用调用(invokev ...

  4. [零基础学JAVA]Java SE应用部分-27.Java IO操作(01)

    JAVA IO操作目标 本季知识点 1.File类 2.RandomAccessFile类 File类 在JAVA中所有的IO操作全部存放在java.io包中. File是唯一一个与文件本身有关的操作 ...

  5. java 1.7 新io 实践 NIO2

    Files 类使用 package com.xinyu.test;import java.io.IOException; import java.nio.ByteBuffer; import java ...

  6. Java基础:常用IO流

    1. 数据流 1.1 概述 数据流是操作基本数据类型的流,分为数据输入流,数据输出流. 1.2 数据输入流 1.DataInputStream:数据输出流允许应用程序以适当方式将基本 Java 数据类 ...

  7. java 拒绝访问_java.io.FileNotFoundException: ……(拒绝访问。)

    java.io.FileNotFoundException: C:\Program Files\Apache Software Foundation\Tomcat 6.0\webapps\jwgl00 ...

  8. Java 8 Friday Goodies:java.io终于成功了!

    在Data Geekery ,我们喜欢Java. 而且,由于我们真的很喜欢jOOQ的流畅的API和查询DSL ,我们对Java 8将为我们的生态系统带来什么感到非常兴奋. 我们已经写了一些关于Java ...

  9. 课程目标IO java

    课程目标IO java

  10. JAVA学生信息管理系统IO流版

    JAVA学生信息管理系统IO流版 1. Student类 public class Student implements Serializable{//学号private int sid;//姓名pr ...

最新文章

  1. 13岁女孩因发布JavaScript无限循环代码被捕
  2. JQuery 扩展多语言支持
  3. 高低压配电系统基础知识,都是非常全面的分享!
  4. nextboolean()_Java Random nextBoolean()方法与示例
  5. 2.15.9.menuconfig的实验学习思路
  6. php mysql 录入_MYSQL+PHP表单录入数据的问题
  7. 联想陈旭东:我们有工匠精神
  8. 微软正式发布Internet Explorer 7.0
  9. 3. Node.js REPL(交互式解释器)
  10. 《金融时报》和麦肯锡:本年度最佳书单
  11. OPencv 灰度直方图、直方图规定化
  12. 分布形态的度量-偏度系数与峰度系数的探讨
  13. python2.x 获取网页内容
  14. 联想服务器pe进系统还原,传授联想如何一键还原系统
  15. 三峡学院计算机调剂,重庆三峡学院2019考研调剂信息公告
  16. [树莓派 PICO(基于MicroPython)]基础教程02-按键测试、按键控制外设LED开关
  17. 【问链-EOS公开课】第十五课 用cleos注册EOS主网账户、投票和发币
  18. [源码解析] PyTorch 分布式(2) ----- DataParallel(上)
  19. 10. 请至少列举5个 PEP8 规范(越多越好)。
  20. java克隆(clone)的两种实现方法

热门文章

  1. dolphinscheduler 2.0.3 Docker部署 不支持mysql的解决办法
  2. 计算机检索系统常用的运算符,计算机信息检索过程中常用的检索表达式 计算机信息检索系统.doc...
  3. 万维网联盟(W3C)创立了 WWW 标准
  4. 2020CVPR对抗样本相关论文整理(无开源代码)
  5. python json.dumps(output) ^ SyntaxError: invalid syntax
  6. python输入年份判断生肖_python年份判断生肖
  7. 学习推荐书籍--C语言
  8. python md5解密方法与技巧_python ---- 爬取 md5解密结果 的小脚本
  9. 小米官网首页(html+css+JavaScript)
  10. mac远程桌面windows