Java基础知识_毕向东_Java基础视频教程笔记(19-21 IO流)
来源:互联网 发布:mysql下create index 编辑:程序博客网 时间:2024/06/05 10:28
18天-06-IO流
字节流和字符流
字节流两个基类:
InputStream,FileInputStream,BufferedInputStream
OutputStream,FileOutputStream,BufferedOutputStream
PrintStream (打印字节流,带编码格式)
字符流两个基类:
Reader,FileReader,BufferedReader,InputStreamReader(字节流转换为字符流读取,带编码格式)
Writer,FileWriter,BufferedWriter,OutputStreamWriter(字节流转换为字符流写入,带编码格式)
PrintWriter (打印字符流,带编码格式)
流操作规律讲解:
源设备: 键盘 System.in; 硬盘 FileStream; 内存 ArrayStream;
目的设备: 控制台 System.out; 硬盘 FileStream; 内存 ArrayStream;
字符流:(只能用于文本文件)
操作FileWriter写入文件:
1.创建一个FileWriter对象,该对象一被初始化就必须要明确被操作的文件。而且该文件会被创建到指定目录下。如果该目录下已经有同名文件,将被覆盖。其实该步骤就是在明确数据要存放的目的地。
FileWriter fw=new FileWriter("filePath",true); //ture代表不覆盖已有文件,并在已有文件末尾添加数据
2.调用write()方法,将字符串写入到流中。
3.刷新流对象中缓冲的数据到文件里。
4.关闭流资源。在关闭流前,会刷新一次内部缓冲区的数据。
操作FileReader读取文件:
1.创建一个文件读取流对象,和指定名称的文件。要保证该文件是已经存在,如果不存在,会发生FileNotFoundException异常。 FileReader fr=new FileReader(FilePath);
2.调用读取流对象的read方法。read();一次读取一个字符,而且会自动往下读取。
第二种通过字符数组进行读取。
定义一个数组,用于存储读取到的字符,读取read(char[])返回的是读取到的字符个数。
复制的原理:其实就是将一个地方的文件数据存储到另外一个指定的地方。
字符流拷贝文件示例:
1 /** 2 * 拷贝文件 3 * 4 * @param sourceFile 源文件路径 5 * @param targetFile 目标文件路径 6 */ 7 public static void copyFile(String sourceFile, String targetFile) 8 { 9 FileReader fr = null; //读文件10 FileWriter fw = null; //写文件11 try12 {13 fr = new FileReader(sourceFile);14 fw = new FileWriter(targetFile);15 16 char[] temp = new char[1024];17 int length = 0;18 while ((length = fr.read(temp)) != -1)19 {20 //length是每次读取文件时返回已读取的字符数量,-1为文件读取完毕21 fw.write(temp, 0, length);22 }23 }24 catch (IOException e)25 {26 e.printStackTrace();27 }28 finally29 {30 try31 {32 if (fr != null)33 {34 fr.close();35 }36 }37 catch (IOException e)38 {39 e.printStackTrace();40 }41 try42 {43 if (fw != null)44 {45 fw.close();46 }47 }48 catch (IOException e)49 {50 e.printStackTrace();51 }52 }53 }
缓冲区: BufferedWriter,BufferedReader
缓冲区的出现是为了提高流的操作效率。所以在创建缓冲区之前,必须要先有流对象。
1.创建流对象(FileReader,FileWriter);
2.将需要提高效率的流对象作为参数传递给缓冲区的构造函数即可;
3.读写数据,并即时刷新缓冲区数据;
4.关闭缓冲区,流对象,缓冲区关闭时会检测一下数据是否写完,所以要后关闭流对象。
字符读取流缓冲区:该缓冲区提供了一个一次读一行的方法readLine(),当返回null时,表示读取到文件末尾。
readLine方法返回的时候只返回回车符之前的数据内容,并不返回包含回车符。
readLine原理:无论是读一行还是读取多个字符,其实最终都是在硬盘上一个一个读取,所以最终使用的还是read()方法一次读一个。
缓冲区提供了一个跨平台的换行符:newLine();
缓冲区拷贝文件示例:
1 /** 2 * 缓冲区拷贝文件 3 * 4 * @param sourceFile 源文件路径 5 * @param targetFile 目标文件路径 6 */ 7 public static void copeFileByBuffer(String sourceFile, String targetFile) 8 { 9 BufferedReader bufr = null;10 BufferedWriter bufw = null;11 try12 {13 bufr = new BufferedReader(new FileReader(sourceFile));14 bufw = new BufferedWriter(new FileWriter(targetFile));15 String temp = null;16 while ((temp = bufr.readLine()) != null)17 {18 bufw.write(temp);19 bufw.newLine();20 bufw.flush();21 }22 }23 catch (FileNotFoundException e)24 {25 e.printStackTrace();26 }27 catch (IOException e)28 {29 e.printStackTrace();30 }31 finally32 {33 try34 {35 if (bufr != null)36 {37 bufr.close();38 }39 }40 catch (IOException e)41 {42 e.printStackTrace();43 }44 try45 {46 if (bufw != null)47 {48 bufw.close();49 }50 }51 catch (IOException e)52 {53 e.printStackTrace();54 }55 }56 }
装饰设计模式:当想要对已有的对象进行功能增强时,可以定义类将已有对象传入,基于已有的功能,并提供增强功能。那么自定义的该类称为装饰类。
装饰类通常会通过构造方法接收被装饰的对象,并基于被装饰的对象的功能,提供更强的功能。
装饰类因为增强了已有的对象,具备的功能和已有的是相同的,只不过提供了更强的功能,所以装饰类和被装饰类通常是都属于一个体系中的。
装饰模式比继承要灵活,避免了继承体系臃肿,而且降低了类与类之间的关系。
字节流:
int read():读取时返回int类型,会把byte字节提升为int类型,提升方式是byte&0xff,在写入时也做了反向操作强转为byte类型。防止类型提升导致原本不是 -1 的数据在类型提升后变成 -1。
字节流复制文件示例:
1 /** 2 * 字节流方式拷贝文件 3 * 4 * @param sourceFile 源文件路径 5 * @param targetFile 目标文件路径 6 */ 7 public static void copyFileByByte(String sourceFile, String targetFile) 8 { 9 BufferedInputStream bfis = null;10 BufferedOutputStream bfos = null;11 try12 {13 bfis = new BufferedInputStream(new FileInputStream(sourceFile));14 bfos = new BufferedOutputStream(new FileOutputStream(targetFile));15 byte[] temp = new byte[1024*1024];16 int length;17 while ((length = bfis.read(temp)) != -1)18 {19 bfos.write(temp, 0, length);20 }21 }22 catch (FileNotFoundException e)23 {24 e.printStackTrace();25 }26 catch (IOException e)27 {28 e.printStackTrace();29 }30 finally31 {32 try33 {34 if (bfis != null)35 {36 bfis.close();37 }38 }39 catch (IOException e)40 {41 e.printStackTrace();42 }43 try44 {45 if (bfos != null)46 {47 bfos.close();48 }49 }50 catch (IOException e)51 {52 e.printStackTrace();53 }54 }55 }
19天-15-IO流读取键盘录入
System.out: 对应的是标准输出设备,控制台。
System.in: 对应的标准输入设备,键盘。
流操作键盘录入示例:
1 /** 2 * 键盘录入,over表示结束 3 */ 4 public static void keyboardEntry() throws IOException 5 { 6 BufferedReader br = null; 7 BufferedWriter bw = null; 8 try 9 {10 br = new BufferedReader(new InputStreamReader(System.in));11 bw = new BufferedWriter(new OutputStreamWriter(System.out));12 String temp;13 while ((temp = br.readLine()) != null)14 {15 if ("over".equals(temp))16 {17 break;18 }19 bw.write(temp);20 bw.newLine();21 bw.flush();22 }23 }24 finally25 {26 if (br != null)27 {28 br.close();29 }30 if (bw != null)31 {32 bw.close();33 }34 }35 }
流操作的基本规律:
通过三方面来确定:
1.明确源和目的
源:输入流,InputStream,Reader
目的:输出流,OutputStream,Writer
2.操作的数据是否是纯文本
是:字符流 否:字节流
3.当体系明确后,再明确要使用哪个具体的对象。
通过设备来区分:源设备:内存,硬盘,键盘;目的设备:内存,硬盘,控制台
注:转换流:主要用于字节流与字符流的转换和在涉及字符编码时指定编码。
20天-01-IO流File类
File类:用来将文件或者文件夹封装成对象,方便对文件与文件夹的属性信息进行操作,File对象可以作为参数传递给流的构造函数。
File类常用方法:
1.创建 boolean createNewFile();//在指定位置创建文件,如果该文件已经存在,则不创建文件返回false
boolean mkdir();//创建文件夹 boolean mkdirs();//创建多级文件夹
2.删除 boolean delete();//删除失败返回false void deleteOnExit();//在程序退出时删除指定文件
3.判断 exists();//文件是否存在 isHidden();//判断是否是隐藏文件 canExecute();//判断文件是否可执行
isFile();//是否是文件 isDirectory();//判断是否是目录 isAbsolute();//判断是否是绝对路径
注:在判断文件对象是否是文件或者目录时,必须要先判断文件对象封装的内容是否存在,通过exists()判断
4.获取 getName();//获取文件名 getPath();//获取文件封装路径 getParent();//获取文件封装父目录
getAbsolutePath();//获取文件绝对路径 lastModified();//获取文件最后修改时间 length();//获取文件大小
删除文件操作示例:
1 /** 2 * 递归遍历删除所有文件 3 * 4 * @param file 文件路径 5 */ 6 public static void deleteFile(File file) 7 { 8 if (!file.exists()) 9 {10 return;11 }12 File[] fileList = file.listFiles();13 for (File f : fileList)14 {15 if (f.isDirectory())16 {17 deleteFile(f);18 }19 else20 {21 f.delete();22 }23 }24 file.delete();25 }
20天-11-IO流Properties类
Properties是hashtable的子类,也就是说它具备map集合的特点,而且它里面存储的键值对都是字符串,是集合和IO技术相结合的集合容器。在加载数据时,需要数据有固定的格式:键=值
打印流:该流提供了打印方法,可以将各种数据类型的数据都原样打印。
字节流打印流:PrintStream 构造函数可以接收的参数类型:
1.file对象,File;2.字符串路径,String;3.字节输出流,OutputStream
字符打印流:PrintWriter 构造函数可以接收的参数类型:
1.file对象,File;2.字符串路径,String;3.字节输出流,OutputStream;4.字符输出流,Writer
序列流SequenceInputStream:将多个数据源的文件流合并到一起。
文件合并流示例:
1 /** 2 * 把多个文件里面的数据合并到一个文件里面 3 * 4 * @param targetFile 合入文件 5 * @param sourceFiles 多个原文件 6 * @throws IOException 7 */ 8 public static void combineTFiles(String targetFile, String... sourceFiles) 9 throws IOException10 {11 ArrayList<FileInputStream> v = new ArrayList<FileInputStream>();12 for (String s : sourceFiles)13 {14 v.add(new FileInputStream(s));15 }16 Iterator<FileInputStream> it = v.iterator();17 Enumeration<FileInputStream> en = new Enumeration<FileInputStream>()18 {19 @Override20 public boolean hasMoreElements()21 {22 return it.hasNext();23 }24 25 @Override26 public FileInputStream nextElement()27 {28 return it.next();29 }30 };31 SequenceInputStream sis = new SequenceInputStream(en);32 FileOutputStream fos = new FileOutputStream(targetFile);33 byte[] bf = new byte[1024];34 int length = 0;35 while ((length = sis.read(bf)) != -1)36 {37 fos.write(bf, 0, length);38 }39 sis.close();40 fos.close();41 }
对象流ObjectInputStream,ObjectOutputStream:被操作的对象需要实现Serializable(标记接口),对象中的transient和static修饰的成员变量不会被读取和写入
实现Serializable接口的类,需要做一个标记方便后期修改 static final long serialVersionUID = 10L;
管道流PipedInputStream,PipedOutputStream:输入输出可以直接进行连接,通过结合多线程使用,先把数据写入管道再从管道里面读取出来。
管道流示例:
1 class Demo 2 { 3 public static void main(String[] args) 4 { 5 //exit为退出管道示例命令 6 PipedInputStream pis = new PipedInputStream(); 7 PipedOutputStream pos = new PipedOutputStream(); 8 //读取管道流连接写入管道流,当有数据写入管道时,读取管道线程自动读入数据 9 pis.connect(pos);10 new Thread(new ReadPiped(pis)).start();11 new Thread(new WritePiped(pos, System.in)).start();12 }13 }14 class ReadPiped implements Runnable15 {16 private PipedInputStream in;17 public ReadPiped(PipedInputStream in)18 {19 this.in = in;20 }21 @Override22 public void run()23 {24 try25 {26 byte[] bt = new byte[1024];27 int len = 0;28 while (true)29 {30 len = in.read(bt);31 String str = new String(bt, 0, len);32 if ("exit".equals(str))33 {34 break;35 }36 System.out.println(str);37 }38 in.close();39 }40 catch (IOException e)41 {42 e.printStackTrace();43 }44 }45 }46 class WritePiped implements Runnable47 {48 private PipedOutputStream out;49 private BufferedReader bf = null;50 public WritePiped(PipedOutputStream out, InputStream in)51 {52 this.out = out;53 bf = new BufferedReader(new InputStreamReader(in));54 }55 @Override56 public void run()57 {58 try59 {60 String temp;61 while (true)62 {63 temp = bf.readLine();64 out.write(temp.getBytes());65 if ("exit".equals(temp))66 {67 break;68 }69 }70 bf.close();71 out.close();72 }73 catch (IOException e)74 {75 e.printStackTrace();76 }77 }78 }
随机访问文件RandomAccessFile:该类不算IO体系中的子类,而是直接继承自Object。但是它是IO包中成员,因为它具备读和写功能,内部封装了一个数组,而且通过指针对数组的元素进行操作,可以通过getFilePointer获取指针位置,同时也可以通过seek修改指针的位置。其实内部完成读写的原理是内部封装了字节输入流和输出流。
如果模式为只读 r,不会创建文件,会去读取一个已存在的文件,如果文件不存在,则会抛异常。
如果模式为读写 rw,操作的文件不存在,会自动创建,如果文件存在则不会覆盖。
特点:可以随机的读写文件里面的数据,用于多线程把数据分段存到一个文件里(多线程下载)。
void seek(long pos); //设置指针位置,方便修改指定位置数据
int skipBytes(int n); //指针向前跳n个字节,不能向后跳
基本数据类型流DataInputStream,DataOutputStream:可以用于操作基本数据类型的数据的流对象
字节数组流
ByteArrayInputStrean:在构造函数里,需要接收数据源,而且数据源是一个字节数组
ByteArrayOutputStream:在构造函数里,不用定义数据目的,该对象内部已经封装了可变长度的字节数组,就是数据目的地。
因为这两个流对象都操作的数组,并没有使用系统资源。所以不用进行close关闭。
void writeTo(OutputStream out); //把数组里面的数据写入流里面
字符数组流 CharArrayReader,CharArrayWriter
字符串流 StringReader,StringWriter
21天-07-字符编码
ASCII:美国标准信息交换码,用一个字节的7位可以表示
ISO8859-1:拉丁码表,欧洲码表,用一个字节的8位表示
GB2312:中国的中文编码表
GBK:中国的中文编码表升级,融合了更多的中文文字字符,用两个字节的8位表示,每个字节前面第一位是标识
Unicode:国际标准码,融合了多种文字,所有文字都用两个字节来表示,Java语言使用的就是Unicode
UTF-8:最多用三个字节来表示一个字符
编码:字符串变成字节数组
String-->byte[]; str.getBytes(charsetName);
解码:字节数组变成字符串
byte[]-->String; new String(byte[],charsetName);
编码转换示例:
1 import java.io.IOException; 2 import java.io.UnsupportedEncodingException; 3 class Demo 4 { 5 public static void main(String[] args)throws IOException 6 { 7 encodeShow("test", "gbk"); 8 encodeShow("test", "utf-8"); 9 encodeShow("test", "GB2312");10 encodeShow("test", "ascii");11 encodeShow("test", "unicode");12 encodeShow("test", "ISO8859-1");13 }14 public static void encodeShow(String param, String charset)15 throws UnsupportedEncodingException16 {17 String str = param;18 sop("source string: " + str + " encode is: " + charset);19 byte[] bt = str.getBytes(charset);20 for (byte b : bt)21 {22 sop("encode binary: " + Integer.toBinaryString(b));23 }24 String t = new String(bt, charset);25 sop("encode string: " + t);26 sop("");27 }28 private static void sop(Object obj)29 {30 System.out.println(obj);31 }32 }
换行符: Linux:\n windows:\r\n Mac:\r
- Java基础知识_毕向东_Java基础视频教程笔记(19-21 IO流)
- Java基础知识_毕向东_Java基础视频教程笔记(13)
- Java基础知识_毕向东_Java基础视频教程笔记(11-12)
- Java基础知识_毕向东_Java基础视频教程笔记(14-18集合框架)
- Java基础知识_毕向东_Java基础视频教程笔记(22-25 GUI 网络编程 正则)
- Java基础知识_毕向东_Java基础视频教程笔记(26 反射)
- 黑马程序员_毕向东_Java基础视频教程第十八天-IO流---学习笔记
- 黑马程序员_毕向东_Java基础视频教程下载
- 黑马程序员_毕向东_Java基础视频教程(九)
- 黑马程序员_毕向东_Java基础视频教程第13天_JavaAPI学习笔记
- 传智播客_毕向东_Java基础视频教程学习笔记(一)
- 黑马程序员_毕向东_Java基础视频教程学习笔记(二)
- 黑马程序员_毕向东_Java基础视频教程学习笔记(三)
- 黑马程序员_毕向东_Java基础视频教程学习笔记(四)
- 黑马程序员_毕向东_Java基础视频教程学习笔记(五)
- 黑马程序员_毕向东_Java基础视频教程学习笔记(六)
- 黑马程序员_毕向东_Java基础视频教程学习笔记(七)
- 黑马程序员_毕向东_Java基础视频教程学习笔记(八)
- Java8揭秘之Default 方法
- HaspMap使用简单方法
- MySQL对表的操作,掌握这些整理就够了吧
- Pat(A) 1100. Mars Numbers (20)
- Linux命令-使用echo命令在文件的末尾追加内容
- Java基础知识_毕向东_Java基础视频教程笔记(19-21 IO流)
- connect的变化使用
- 【Java】ArrayList<String>转化为String数组问题
- linux运维学习之路
- 代码的文件和路径命名规范和目录结构规划
- Python学习之使用Future对象来异步返回结果方法详解
- 截取List集合中的一部分,组成新的List集合
- python3 使用代理访问
- Linux内核tcp参数解析