黑马程序员_java学习日记_Java基础_IO
输入输出流
字节字符流:
字符流融合了编码表,图片字节流
publicstaticvoid main(String[] args) {
?????? //创建一个文件对象,该对象一杯初始化就必须要有被操作的文件
?????? //该文件会被创建在指定文件目录下,如果该目录有同名文件将被覆盖
?????? //其实就是明确数据存放的目的地
?????? FileWriter f = null;
?????? try {
?????????? f = new FileWriter("demo.txt");
?????????? //将数据写入到流中即缓存
?????????? f.write("aa");
?????????? //刷新流对象中的数据到文件中
?????????? f.flush();
?????? } catch (IOException e) {
?????????? // TODO Auto-generated catch block
?????????? e.printStackTrace();
?????? } finally
?????? {
?????????? try {
????????????? f.close();
?????????? } catch (IOException e) {
????????????? e.printStackTrace();
?????????? }
?????? }
??? }Close:关闭流资源,关闭之前刷新一次流资源
Flush:刷新后,流可以继续使用
Java本身不能写数据,但是java可以靠系统内部的方式去完成书写,使用完必须释放
文件的续写
FileWriter f = null;
?????? try {
?????????? System.out.println("13");
?????????? f = new FileWriter("demo.txt",true);
?????????? //换行
?????????? f.write("\r\n123213");
?????? } catch (IOException e) {
?????????? e.printStackTrace();
?????? }
文件的单个读取
FileReader f = new FileReader("demo.txt");
?????? //read是一次读一个字符,而且自动往下读
?????? //如果读到末尾返回-1
?????? //read方法操作的其实是读取磁盘的磁头
?????? char c = (char) f.read();
?????? System.out.println(c);
第二种方式:通过字符数组进行读取
publicstaticvoid main(String[] args) throws IOException {
?????? FileReader f = new FileReader("demo.txt");
?????? char [] c = newchar[31];
?????? //如果字符长度不够会添口
?????? int num;
?????? while((num=f.read(c))!=-1)
?????? {
?????????? System.out.println(new String(c,0,num));
?????? }
??? }
复制文件:
?
缓冲区:缓冲区的出现是为了提高流的效率,所以在创建缓冲区之前,必须要先有流对象
缓冲技术的原理就是对象里面封装了数组
写入
publicstaticvoid main(String[] args) throws IOException {
?????? FileWriter fw = new FileWriter("demo.txt");
?????? //只要将需要提高效率的流对象作为参数传递给缓冲区的构造函数即可
?????? BufferedWriter bw = new BufferedWriter(fw);
?????? bw.write("aaa");
?????? //只要用到缓冲区就要记得刷新
?????? //其实关闭缓冲器就是在关闭缓冲区所操作的流对象,所以无需关闭FW
?????? bw.flush();
?????? bw.close();
??? }
NewLine//提供的跨平台的换行
读取
publicstaticvoid main(String[] args) throws IOException {
?????? //创建一个读取流与文件相关联
?????? FileReader fr = new FileReader("demo.txt");
?????? //为了提高效率加入缓冲技术,将字符流作为参数传给构造函数
?????? BufferedReader br = new BufferedReader(fr);
?????? String s = null;
?????? //该缓冲区提供了一个一次读一行的方法,放该方法返回null时表示读到文件末尾
?????? while( (s = br.readLine()) != null)
?????? {
?????? System.out.println(s);??
?????? }
?????? br.close();
??? }
缓冲区复制文件
?
publicstaticvoid main(String[] args) {
?????? BufferedReader br = null;
?????? BufferedWriter bw = null;
?????? try {
?????????? br = new BufferedReader(new FileReader("FileDemo1.java"));
?????????? bw = new BufferedWriter(new FileWriter("FileDemo1.txt"));
?????????? String str = null;
?????????? //readLine只返回回车符之前的内容,并不返回回车符
?????????? while((str = br.readLine())!=null)
?????????? {
????????????? System.out.println(str);
????????????? bw.write(str);
????????????? bw.newLine();
????????????? bw.flush();
?????????? }
?????? } catch (Exception e) {
?????????? e.printStackTrace();
?????? }
??? }
Readline图解
Readline最终使用的还是read方法一个一个读
装饰设计模式:当想要对已有对象进行功能增强时,可以定义一个类,将已有对象传入,基于已有对象功能,并提供加强功能,那么自定义的该类就成为装饰类、
装饰设计模式与继承的区别:装饰模式比继承灵活,避免了继承体系的臃肿,降低了类与类之间的关系
装饰类因为增强以有对象,具备功能和已有相同,只不过提供了更强功能,所以装饰类和被装饰类通常属于同一个体系
LineNumberReader
publicstaticvoid main(String[] args) throws IOException {
?????? FileReader r = new FileReader("FileDemo1.java");
?????? LineNumberReader lb = new LineNumberReader(r);
?????? //起始行号
?????? lb.setLineNumber(14);
?????? String str = null;
?????? while((str = lb.readLine()) != null)
?????? {
?????????? //顺便读出行号
?????????? System.out.println(lb.getLineNumber()+str);
?????? }
??? }
字符流底层用的是字节流的缓冲区,字节流不需要刷新,因为字节是最小单位,而字符需要转换因此不需要flush,但是需要close
复制一个图片
//用字节流读取图片
??? //用字节流创建一个文件,用于存贮读入字节
??? //循环读写,完成存贮
??? //关闭资源
??? publicstaticvoid main(String[] args) throws IOException {
?????? FileInputStream in = new FileInputStream("f:\\1.jpg");
?????? FileOutputStream out = new FileOutputStream("f:\\2.jpg");
?????? byte[] b = newbyte[1024];
?????? int length;
?????? while((length = in.read(b))!=-1)
?????? {
?????????? out.write(b);
?????? }
?????? out.close();
?????? in.close();
??? }
缓冲流读取音频文件
publicstaticvoid main(String[] args) throws IOException {
?????? BufferedInputStream in = new BufferedInputStream(new FileInputStream("f:\\[迅雷下载www.2tu.cc]麻辣隔壁06.rmvb"));
?????? BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("f:00007.rmvb"));
?????? int i = 0;
?????? while((i = in.read())!= -1)
?????? {
?????????? out.write(i);
?????? }
?????? out.close();
?????? in.close();
??? }
为什么read方法返回的不是byte类型,而是int避免了-1的发生,而write方法将最低的一个字节写出去,保证了元数据的原样型
BufferedReader
BufferedWriter
FileReader
FileWriter
BufferedInputStream
FileInputStream
BufferedOutputStream
FileOutputStream
键盘录入
Read是一个阻塞数据,没有录入数据就会等待
/r == 13
/n == 10
//转换流
?????? BufferedReader bo = new BufferedReader(new InputStreamReader(System.in));
?????? BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
?
流操作的基本规律,最痛苦的是流对象不知道用哪个,通过两个明确来完成
1,? 明确源和目的
源:输入流 inputstream reader
目的:输出流 outputstream writer
2,? 明确操作的数据是否是纯文本
是:字符流:
不是:字节流:
3,? 当体系明确后,在明确要使用的对象
通过设备来进行区分
内存
硬盘
键盘
publicstaticvoid main(String[] args) throws IOException {
?????? //设置输入流为某个文件
?????? System.setIn(new FileInputStream("FileDemo1.java"));
?????? //System.setOut//设置输出流为某个文件
?????? //转换流
?????? BufferedReader bo = new BufferedReader(new InputStreamReader(System.in));
?????? BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
?????? int i = 0;
?????? while((i = bo.read())!=-1)
?????? {
?????????? bw.write(i);
?????? }
?????? bw.close();
?????? bo.close();
}
异常的日志文件
publicstaticvoid main(String[] args) throws FileNotFoundException {
?????? try {
?????????? int [] a = newint[2];
?????????? System.out.println(a[3]);
?????? } catch (Exception e) {
?????????? e.printStackTrace(new PrintStream("a.txt"));
?????? }
}
?
publicstaticvoid main(String[] args) throws FileNotFoundException {
?????? Properties p = System.getProperties();
?????? //将java虚拟机的信息保存到文件上
?????? p.list(new PrintStream("a.java"));
?
}
File用来将文件或者文件夹封装成对象的类,方便操作文件
流只能操作数据,file才能才做文件
//将a.txt封装成对象,可以将已有的或者未出现的文件或者文件夹封装成文件
?????? File f = new File("d:\\a.txt");
?????? //File.separator 目录分隔符
?????? File f1 = new File("d:"+File.separator+"abc","a.txt");
?????? //File f = new File("d:\\abc\\a.txt");
?????? //File d = new File("d:\");
?????? //File e = new File(d,"aaa.txt");
?
}
?
创建和删除文件
publicstaticvoid main(String[] args) throws IOException {
?????? File file = new File("test.log");
?????? //在指定位置创建文件,如果该文件已经存在,则不创建返回false
?????? //输出流是直接覆盖掉文件
?????? /*createTempFile(String prefix, String suffix)
??????? 在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称。
??????? createTempFile(String prefix, String suffix, File directory)
??????? 在指定目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。*/
?????? //delete:删除失败返回false
?????? //deleteonExit:一定会删除文件,而delete不一定即使是在finally中
?????? file.createNewFile();
??????
?????? file.delete();
}
创建目录和文件以及file的判断方法
publicstaticvoid main(String[] args) throws IOException {
?????? File file = new File("a.txt");
?????? //判断文件是否存在
?????? System.out.println(file.exists());
?????? File f = new File("abc");
?????? File f1 = new File("a\\b\\c");
?????? //只能创建一级文件夹
?????? f.mkdir();
?????? //创建多级文件夹
?????? f1.mkdirs();
?????? //在判断文件对象是否是文件或者目录时必须先判断该文件是否存在
?????? file.createNewFile();
?????? System.out.println(file.isFile());
?????? System.out.println(file.isDirectory());
?????? //isFile
?????? //isDirectory
?????? //isHidden
??? ??? //isAbsolute
}
关于file的路径问题
publicstaticvoid main(String[] args) {
?????? File file = new File("file.txt");
?????? //封装的是什么路径,获取的就是什么路径,无论文件是否存在
?????? System.out.println(file.getPath());
?????? //无论封装的是什么路径,获取的就是绝对路径,无论文件是否存在
?????? System.out.println(file.getAbsolutePath());
?????? //该方法返回的是绝对路径的父目录,如果返回相对路径,返回null
?????? //如果相对路径中有一层上机目录(abc//file.txt)那么该方法就返回上机目录
?????? System.out.println(file.getParent());
?????? System.out.println(file.lastModified());
??????
}
文件过滤
publicstaticvoid main(String[] args) {
?????? //获取根目录
?????? File[] files = File.listRoots();
?????? for(File file : files)
?????? {
?????????? System.out.println(file.toString());
?????? }
?????? File file = new File("D:\\ec\\Test01");
?????? String[] str = file.list();
?????? //过滤出符合条件的文件
?????? String[] str1 = file.list(new FilenameFilter() {
??????????
?????????? @Override
?????????? publicboolean accept(File dir, String name) {
????????????? return name.endsWith(".java");
?????????? }
?????? });
?????? //调用list方法的file对象必须是封装了一个目录,该目录还必须存在
?????? System.out.println(str.length);
?????? System.out.println(str1.length);
}
递归:再循环的过程中重复调用一个同一个方法,这种手法叫做递归
递归要注意死循环
??? 注意限定条件
??? 注意内存溢出
/**
?* 递归
?* @author Alex Shaw
?*
?*/
publicclass FileDemo_digui {
?
??? publicstaticvoid digui(File file)
??? {
?????? System.out.println(file);
?????? File[] file1 = file.listFiles();
?????? for(File f:file1)
?????? {
?????????? //是目录就递归不是就不递归
?????????? if(f.isDirectory())
?????????? {
????????????? digui(f);
?????????? }else
?????????? {
????????????? System.out.println(f.getName());
?????????? }
??????????
?????? }
??? }
??? publicstaticvoid main(String[] args) {
?????? File file = new File("d:\\ec");
?????? digui(file);
??? }
}
二进制递归
??? /**
??? ?* 二进制递归
??? ?* @param args
??? ?*/
??? publicstaticvoid main(String[] args) {
?????? binary(4);
??? }
??? publicstaticvoid binary(int a)
??? {
?????? if(a>0)
?????? {
?????????? binary(a/2);
?????????? System.out.print(a%2);
?????? }else
?????? {
?????????? return;
?????? }
}
递归删除,从里往外删除
publicclass Filedemo17 {
??? publicstaticvoid main(String[] args) {
??? }
??? //java删除不走回收站
??? publicstaticvoid remove(File file)
??? {
??? File[] files = file.listFiles();
??? for(File f : files)
??? {
?????? if(f.isDirectory())
?????? {
?????????? remove(f);
?????? }else
?????? {
?????????? f.delete();
?????? }
??? }
??? }
}
将java绝对路径存到文件中
publicstatic String readInFile(File file)
??? {
?????? StringBuffer sb = new StringBuffer();
?????? File[] files = file.listFiles();
?????? for(File f:files)
?????? {
?????????? if(f.isDirectory())
?????????? {
????????????? readInFile(f);
?????????? }else
?????????? {
????????????? sb.append(f.getAbsolutePath()+f.getName());
?????????? }
?????? }
?????? return sb.toString();
}
Properties
是hashtable的子类
也就是说它具有hashtable的特点,里面存贮的都是字符串
是集合中与IO想结合的容器
该对象特点:可以用于键值对形式的配置文件
//用一个流与文件关联
??? //读一行数据用=分割
??? //左为键右为值
??? //...现在可以直接使用load方法来操作properties文件
??? publicvoid getFromFile() throws IOException
??? {
?????? BufferedReader br = new BufferedReader(new FileReader("a.txt"));
?????? String str = null;
?????? while((str = br.readLine())!=null)
?????? {
?????????? System.out.println(br.readLine());
?????? }
??? }
??? publicvoid load() throws IOException
??? {
?????? Properties p = new Properties();
?????? BufferedReader br = new BufferedReader(new FileReader("a.txt"));
?????? p.load(br);
}
Property不仅能加载流数据,还能将集合中的数据存储到指定文件中
Setpropertiey改变的是内存的结果
Store是改变流或者是文件上的内容
加载数据时有固定的格式“键”=“值”
打印流提供了打印方法
字符打印流,printWriter(字节输出流,字符输出流)
字节打印流,printstream(能直接操作文件,还可以指定字符集,字符串路径,字节输出流)
publicstaticvoid main(String[] args) throws IOException {
?????? BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
?
?????? PrintWriter pw = new PrintWriter(System.out,true);
?????? String str = null;
?????? while((str = br.readLine())!=null)
?????? {
?????????? pw.write(str);
?????????? System.out.println(str);
?????? }
?????? pw.close();
?????? br.close();
}
SequenceInputStream:将多个流拼成一个流对象
切割文件和合并文件
??? publicstaticvoid main(String[] args) throws IOException {
?????? Vector<InputStream> vi = new Vector<InputStream>();
?????? vi.add(new FileInputStream("c:\\1.txt"));
?????? vi.add(new FileInputStream("c:\\2.txt"));
?????? vi.add(new FileInputStream("c:\\3.txt"));
?????? SequenceInputStream s = new SequenceInputStream(vi.elements());
?????? FileOutputStream f = new FileOutputStream("c:\\4.txt");
?????? byte[] b = newbyte[1024];
?????? int len;
?????? while((len = s.read(b))!= -1)
?????? {
?????????? f.write(b);
?????? }
??????
??? }
??? publicvoid split() throws IOException
??? {
?????? FileInputStream fis = new FileInputStream("c:\\1.bmp");
?????? FileOutputStream out = null;
?????? byte[]b = newbyte[1024];
?????? int len;
?????? int count;
?????? while((len = fis.read(b))!= -1)
?????? {
?????????? out = new FileOutputStream("c:\\a.sds");
?????????? out.write(b,0,len);
?????????? out.close();
?????? }
}
RandomAccessFile:该类不是IO包下的子类,而是直接集成Object
但是他是IO包中的成员,因为他具备读写功能,内部封装了一个数组,通过指针对数组中的元素进行操作,可以通过getFilterPointer获取指针,同时可以通过seek方法改变指针位置
其实能完成读写是因为他内部封装了字节输入流和输出流
该类只能操作文件
通过指针的偏移可以去任意的数据,但是必须文件是有规律的
skipBytes只能往后走,不能往回走
seek可以任意选择指针
如果模式为只读,不会创建文件,会去读取一个已存在的文件,如果不存在回报异常
如果模式为rw,则会创建文件,存在不会覆盖
