Java基础08——I/O流<一>
来源:互联网 发布:淘宝评价管理在哪里找 编辑:程序博客网 时间:2024/05/20 20:46
------- android培训、java培训、期待与您交流! ----------
IO流:用于处理设备之间的数据传输
按操作数据分为:字节流和字符流流
按流向分为:输入流,输出流
输入:将外设中的数据读取到内存中
输出:将内存的数据写入到外设中
缓冲的原理:从源中获取一批数据装进缓冲区中,再从缓冲区中不断取出一个个数据,取完后再从源中继续取一批数据进缓冲区。当源中数据取完,用-1作结束。
思路:缓冲区就是封装了一个数组,并对外提供了更多的方法对数组进行访问,其实这些方法最终操作的都是数组的角标
IO流一般使用原则:
一、按数据来源(去向)分类:
2、是byte[]:ByteArrayInputStream, ByteArrayOutputStream
3、是Char[]: CharArrayReader, CharArrayWriter
4、是String: StringBufferInputStream, StringReader, StringWriter
5、网络数据流:InputStream, OutputStream, Reader, Writer
二、按是否格式化输出分:
要格式化输出:PrintStream, PrintWriter
三、按是否要缓冲分:
要缓冲:BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter
四、按数据格式分:
1、二进制格式(只要不能确定是纯文本的): InputStream, OutputStream及其所有带Stream结束的子类
2、纯文本格式(含纯英文与汉字或其他编码方式);Reader, Writer及其所有带Reader, Writer的子类
五、按输入输出分:
1、输入:Reader, InputStream类型的子类
2、输出:Writer, OutputStream类型的子类
六、特殊需要:
1、从Stream到Reader,Writer的转换类:InputStreamReader, OutputStreamWriter
2、对象输入输出:ObjectInputStream, ObjectOutputStream
3、进程间通信:PipeInputStream, PipeOutputStream, PipeReader, PipeWriter
4、合并输入:SequenceInputStream
5、更特殊的需要:PushbackInputStream, PushbackReader, LineNumberInputStream, LineNumberReader
File类常见方法:
1,创建。
boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false。
和输出流不一样,输出流对象一建立创建文件。而且文件已经存在,会覆盖。
boolean mkdir():创建文件夹。
boolean mkdirs():创建多级文件夹。
2,删除。
boolean delete():删除失败返回false。如果文件正在被使用,则删除不了返回falsel。
void deleteOnExit();在程序退出时删除指定文件。
3,判断。
boolean exists() :文件是否存在.
isFile():
isDirectory();
isHidden();
isAbsolute();
4,获取信息。
getName():
getPath():
getParent():
getAbsolutePath()
long lastModified()
long length()
<span style="font-size:12px;"><span style="font-size:12px;"><span style="font-size:12px;"><span style="font-family:Arial;font-size:12px;"><span style="font-family:Arial;font-size:12px;"><span style="font-family:Arial;font-size:12px;"><span style="font-size:12px;">/* * 创建一个可以往文件写入字符数据的字符输出对象。 * 同时明确该文件(用于存储数据目的地) * 如果文件不存在,会自动创建,否则会被覆盖 */public class FileWriterDemo {private static final String LINE_SEPARATOR = System.getProperty("line.separator");public static void main(String[] args) throws IOException {// 构造函数加入"true",可以实现对文件续写FileWriter fw = new FileWriter("demo.txt", true);// write方法写入数据到临时存储缓冲区fw.write("abcds" + LINE_SEPARATOR + "HAAE");// fw.flush();//刷新数据到目的地// 关闭流。关闭前会先调用flush方法。fw.close();}}</span></span></span></span></span></span></span>
<span style="font-size:12px;"><span style="font-size:12px;"><span style="font-size:12px;"><span style="font-family:Arial;font-size:12px;"><span style="font-family:Arial;font-size:12px;"><span style="font-family:Arial;font-size:12px;"><span style="font-size:12px;">public class FileReaderDemo {public static void main(String[] args) {FileReader fr = null;try {fr = new FileReader("demo.txt");char[] buf = new char[1024];int len = 0;while ((len = fr.read(buf)) != -1) {System.out.println(new String(buf, 0, len));}} catch (IOException e) {System.out.println("读取异常" + e.toString());} finally {if (fr != null) {try {fr.close();} catch (IOException e1) {System.out.println("关闭异常" + e1.toString());}}}}}</span></span></span></span></span></span></span>
<span style="font-size:12px;"><span style="font-size:12px;"><span style="font-size:12px;"><span style="font-family:Arial;font-size:12px;"><span style="font-family:Arial;font-size:12px;"><span style="font-family:Arial;font-size:12px;">public class MyBufferedReader extends Reader {private Reader r;private char[] buf = new char[1024];private int pos = 0;private int count = 0;MyBufferedReader(Reader r) {this.r = r;}/* * //1,从源中获取一批数据到缓冲区中。需要先做判断,只有计数器为0时,才需要从源中获取数据。 if(count==0){ count = * r.read(buf); if(count<0) return -1; 每次获取数据到缓冲区后,角标归零. pos = 0; char ch = * buf[pos]; */public int myRead() throws IOException {if (count == 0) {count = r.read(buf);pos = 0;}if (count < 0)return -1;char ch = buf[pos++];count--;return ch;}public String myReadLine() throws IOException {// 定义一个StringBuilder容器,最终还要将数据转为字符串StringBuilder sb = new StringBuilder();int ch = 0;while ((ch = r.read()) != -1) {// 因为Window下每一行回车的字符是'\r\n',要作判断if (ch == '\r')continue;// 如果是回车符,说明行结束,返回字符串if (ch == '\n')return sb.toString();// 行未结束,则继续添加字符elsesb.append((char) ch);}// 防止最后一行遗漏,判断sb不为空则返回最后一行数据if (sb.length() != 0)return sb.toString();return null;}public void myClose() throws IOException {r.close();}@Overridepublic void close() throws IOException {r.close();}@Overridepublic int read(char[] cbuf, int off, int len) throws IOException {return r.read(cbuf, off, len);}}</span></span></span></span></span></span>
<span style="font-size:12px;"><span style="font-size:12px;"><span style="font-size:12px;"><span style="font-family:Arial;font-size:12px;"><span style="font-family:Arial;font-size:12px;"><span style="font-family:Arial;font-size:12px;">public class MyBufferedReaderDemo {public static void main(String[] args) throws IOException {FileReader fr = new FileReader("buf.txt");MyBufferedReader myBuf = new MyBufferedReader(fr);// 按单个字符打印方式打印出数据int i = 0;while ((i = myBuf.myRead()) != -1) {System.out.print((char) i);}// 按一行字符打印方式打印出数据String line = null;while ((line = myBuf.myReadLine()) != null) {System.out.println(line);}myBuf.myClose();}}</span></span></span></span></span></span>
装饰设计模式:
当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有功能,并提供加强功能,称该类为装饰类。
装饰类通常会通过构造方法接收被装饰的对象。装饰和继承都能实现一样的特点:进行功能的扩展增强,但是装饰比继承灵活,装饰的特点:装饰类和被装饰类都
必须所属同一个接口或者父类。避免了继承体系臃肿,降低了类与类之间的关系。
<span style="font-size:12px;"><span style="font-size:12px;"><span style="font-size:12px;"><span style="font-family:Arial;font-size:12px;"><span style="font-family:Arial;font-size:12px;"><span style="font-family:Arial;font-size:12px;">public class LineNumberReaderDemo {public static void main(String[] args) throws IOException {FileReader fr = new FileReader("Demo.txt");LineNumberReader lnr = new LineNumberReader(fr);String line = null;lnr.setLineNumber(100);while ((line = lnr.readLine()) != null) {System.out.println(lnr.getLineNumber() + ":" + line);}lnr.close();}}</span></span></span></span></span></span>
转换流适用原则:
1. 源或者目的对应的设备是字节流,但是操作的却是文本数据,可以使用转换作为桥梁。提高对文本操作的便捷。
2. 一旦操作文本涉及到具体的指定编码表时,必须使用转换流 。
<span style="font-size:12px;"><span style="font-size:12px;"><span style="font-size:12px;"><span style="font-family:Arial;font-size:12px;"><span style="font-family:Arial;font-size:12px;"><span style="font-family:Arial;font-size:12px;">public class TransStreamDemo {public static void main(String[] args) throws IOException, IOException {writeText_2();writeText_3();}public static void readText_2() throws IOException, FileNotFoundException {InputStreamReader isr = new InputStreamReader(new FileInputStream("demo.txt"), "utf-8");char[] buf = new char[10];int len = isr.read(buf);String str = new String(buf, 0, len);System.out.println(str);isr.close();}public static void writeText_3() throws IOException {OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("u8_1.txt"), "utf-8");osw.write("你好");osw.close();}public static void writeText_2() throws IOException {OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk_3.txt"), "GBK");// FileWriter fw = new FileWriter("gbk_3.txt");/* * 两句代码的功能等同 FileWriter其实就是转换流指定了本机默认码表的体现,而且这个转换流的子类对象可以方便操作文本文件 * 即FileReader/FileWriter = InputStreamReader/OutputStreamWriter + * 本机默认的编码表 如果操作的文件需要明确具体的编码,就必须用转换流 */osw.write("你好");osw.close();}}</span></span></span></span></span></span>
递归:函数自身直接或间接调用到自身
<span style="font-size:12px;"><span style="font-size:12px;"><span style="font-size:12px;"><span style="font-family:Arial;font-size:12px;"><span style="font-family:Arial;font-size:12px;"><span style="font-family:Arial;font-size:12px;">/* * 对指定目录进行所有内容的列出。 */public class FileTest {public static void main(String[] args) {File dir = new File("d:\\workspace");// 传入初始文件目录及相应层级listAll(dir, 0);}public static void listAll(File dir, int level) {// 打印传入的文件目录下文件名称System.out.println(getSpace(level) + dir.getName());// 层级++level++;// 获取指定目录下当前所有文件夹或者文件对象File[] files = dir.listFiles();// 便利对象,判断是否包含文件,是,则返回调用listAll方法,否,则打印for (int x = 0; x < files.length; x++) {if (files[x].isDirectory()) {listAll(files[x], level);} elseSystem.out.println(getSpace(level) + files[x].getName());}}private static String getSpace(int level) {StringBuilder sb = new StringBuilder();sb.append("|--");for (int x = 0; x < level; x++) {sb.insert(0, "| ");}return sb.toString();}}</span></span></span></span></span></span>
<span style="font-size:12px;"><span style="font-size:12px;"><span style="font-size:12px;"><span style="font-family:Arial;font-size:12px;"><span style="font-family:Arial;font-size:12px;">public class RemoveDirTest {public static void main(String[] args) throws IOException {File dir = new File("e:\\demodir");removeDir(dir);}public static void removeDir(File dir) throws IOException {File[] files = dir.listFiles();for (File file : files) {if (file.isDirectory()) {removeDir(file);} else {System.out.println(file + ":" + file.delete());}System.out.println(file + ":" + file.delete());}}}</span></span></span></span></span>
Map
|--Hashtable
|--Properties:
Properties集合:
特点:
1,该集合中的键和值都是字符串类型。
2,集合中的数据可以保存到流中,或者从流获取。
通常该集合用于操作以键值对形式存在的配置文件。
<span style="font-size:12px;"><span style="font-size:12px;"><span style="font-size:12px;"><span style="font-family:Arial;font-size:12px;"><span style="font-family:Arial;font-size:12px;">public class PropertiesTest {/** * @param args * @throws IOException * @throws Exception */public static void main(String[] args) throws IOException {getAppCount();}public static void getAppCount() throws IOException {// 将配置文件封装成File对象。File confile = new File("count.properties");if (!confile.exists()) {confile.createNewFile();}FileInputStream fis = new FileInputStream(confile);Properties prop = new Properties();prop.load(fis);// 从集合中通过键获取次数。String value = prop.getProperty("time");// 定义计数器。记录获取到的次数。int count = 0;if (value != null) {count = Integer.parseInt(value);if (count >= 5) {// System.out.println("使用次数已到,请注册,给钱!");// return;throw new RuntimeException("使用次数已到,请注册,给钱!");}}count++;// 将改变后的次数重新存储到集合中。prop.setProperty("time", count + "");FileOutputStream fos = new FileOutputStream(confile);prop.store(fos, "");fos.close();fis.close();}}</span></span></span></span></span>
<span style="font-size:12px;"><span style="font-size:12px;"><span style="font-size:12px;"><span style="font-family:Arial;font-size:12px;"><span style="font-family:Arial;font-size:12px;">/* * 简单说,就是建立一个指定扩展名的文件的列表。 * * 思路: * 1,必须进行深度遍历。 * 2,要在遍历的过程中进行过滤。将符合条件的内容都存储到容器中。 * 3,对容器中的内容进行遍历并将绝对路径写入到文件中。 */public class Test {public static void main(String[] args) throws IOException {File dir = new File("d:\\java");FilenameFilter filter = new FilenameFilter() {@Overridepublic boolean accept(File dir, String name) {return name.endsWith(".java");}};List<File> list = new ArrayList<File>();getFiles(dir, filter, list);File destFile = new File(dir, "javalist.txt");write2File(list, destFile);}/** * 对指定目录中的内容进行深度遍历,并按照指定过滤器,进行过滤, 将过滤后的内容存储到指定容器List中。 * * @param dir * @param filter * @param list */public static void getFiles(File dir, FilenameFilter filter, List<File> list) {File[] files = dir.listFiles();for (File file : files) {if (file.isDirectory()) {// 递归啦!getFiles(file, filter, list);} else {// 对遍历到的文件进行过滤器的过滤。将符合条件File对象,存储到List集合中。if (filter.accept(dir, file.getName())) {list.add(file);}}}}public static void write2File(List<File> list, File destFile)throws IOException {BufferedWriter bufw = null;try {bufw = new BufferedWriter(new FileWriter(destFile));for (File file : list) {bufw.write(file.getAbsolutePath());bufw.newLine();bufw.flush();}} catch (IOException e) {throw new RuntimeException("写入失败");} finally {if (bufw != null)try {bufw.close();} catch (IOException e) {throw new RuntimeException("关闭失败");}}}}</span></span></span></span></span>
PrintStream:提供打印方法对多种数据类型值进行打印,并保持数据的表现形式,即保证数据原样性;不抛IOException
'\n'
) 时都会刷新输出缓冲区<span style="font-size:12px;"><span style="font-size:12px;"><span style="font-size:12px;">public class SequenceDemo {public static void main(String[] args) throws IOException {Vector<FileInputStream> v = new Vector<FileInputStream>();v.add(new FileInputStream("1.txt"));v.add(new FileInputStream("2.txt"));v.add(new FileInputStream("3.txt"));//返回v的组件的枚举,生成Enumeration对象Enumeration<FileInputStream> en = v.elements();SequenceInputStream sis = new SequenceInputStream(en);FileOutputStream fos = new FileOutputStream("4.txt");byte[] buf = new byte[1024];int len = 0;while ((len = sis.read(buf)) != -1) {fos.write(buf, 0, len);}fos.close();sis.close();}}</span></span></span>
<span style="font-size:12px;"><span style="font-size:12px;"><span style="font-size:12px;">public class SplitFile {public static void main(String[] args) throws IOException {// splitFile();merge();}public static void merge() throws IOException {ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();for (int x = 1; x <= 3; x++) {al.add(new FileInputStream("splitFiles\\" + x + ".part"));}final Iterator<FileInputStream> it = al.iterator();Enumeration<FileInputStream> en = new Enumeration<FileInputStream>() {@Overridepublic boolean hasMoreElements() {return it.hasNext();}@Overridepublic FileInputStream nextElement() {return it.next();}};SequenceInputStream sis = new SequenceInputStream(en);FileOutputStream fos = new FileOutputStream("splitFiles\\eagle1.mp3");byte[] buf = new byte[1024];int len = 0;while ((len = sis.read(buf)) != -1) {fos.write(buf, 0, len);}fos.close();sis.close();}public static void splitFile() throws IOException {FileInputStream fis = new FileInputStream("eagle_copy.mp3");FileOutputStream fos = null;byte[] buf = new byte[1024 * 1024];int len = 0;int count = 1;while ((len = fis.read(buf)) != -1) {fos = new FileOutputStream("splitFiles\\" + (count++) + ".part");fos.write(buf, 0, len);fos.close();}fis.close();}}</span></span></span>
需求:切割合并文件流和配置文件
<span style="font-size:12px;"><span style="font-size:12px;"><span style="font-size:12px;">public class MergeFile {/** * @param args * @throws IOException */public static void main(String[] args) throws IOException {File dir = new File("partFiles");mergeFile_2(dir);}// 根据配置文件合并分割文件public static void mergeFile_2(File dir) throws IOException {/* * 获取指定目录下的配置文件对象。 */// 自定义扩展名过滤器,实现了FilenameFilterFile[] files = dir.listFiles(new SuffixFilter(".properties"));if (files.length != 1)throw new RuntimeException(dir + ",该目录下没有properties扩展名的文件或者不唯一");// 记录配置文件对象。File confile = files[0];// 获取该文件中的信息================================================。Properties prop = new Properties();FileInputStream fis = new FileInputStream(confile);prop.load(fis);String filename = prop.getProperty("filename");int count = Integer.parseInt(prop.getProperty("partcount"));// 获取该目录下的所有碎片文件。 ==============================================File[] partFiles = dir.listFiles(new SuffixFilter(".part"));if (partFiles.length != (count - 1)) {throw new RuntimeException(" 碎片文件不符合要求,个数不对!应该" + count + "个");}// 将碎片文件和流对象关联 并存储到集合中。ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();for (int x = 0; x < partFiles.length; x++) {al.add(new FileInputStream(partFiles[x]));}// 将多个流合并成一个序列流。Enumeration<FileInputStream> en = Collections.enumeration(al);SequenceInputStream sis = new SequenceInputStream(en);FileOutputStream fos = new FileOutputStream(new File(dir, filename));byte[] buf = new byte[1024];int len = 0;while ((len = sis.read(buf)) != -1) {fos.write(buf, 0, len);}fos.close();sis.close();}public static void mergeFile(File dir) throws IOException {ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();for (int x = 1; x <= 3; x++) {al.add(new FileInputStream(new File(dir, x + ".part")));}Enumeration<FileInputStream> en = Collections.enumeration(al);SequenceInputStream sis = new SequenceInputStream(en);FileOutputStream fos = new FileOutputStream(new File(dir, "1.bmp"));byte[] buf = new byte[1024];int len = 0;while ((len = sis.read(buf)) != -1) {fos.write(buf, 0, len);}fos.close();sis.close();}}</span></span></span>
<span style="font-size:12px;"><span style="font-size:12px;"><span style="font-size:12px;">public class SplitFileDemo {private static final int SIZE = 1024 * 1024;/** * @param args * @throws Exception */public static void main(String[] args) throws Exception {File file = new File("eagle_copy.mp3");splitFile_2(file);}private static void splitFile_2(File file) throws IOException {// 用读取流关联源文件。FileInputStream fis = new FileInputStream(file);// 定义一个1M的缓冲区。byte[] buf = new byte[SIZE];// 创建目的。FileOutputStream fos = null;int len = 0;int count = 1;/* * 切割文件时,必须记录住被切割文件的名称,以及切割出来碎片文件的个数。 以方便于合并。 * 这个信息为了进行描述,使用键值对的方式。用到了properties对象 */Properties prop = new Properties();File dir = new File("partFiles");if (!dir.exists())dir.mkdirs();while ((len = fis.read(buf)) != -1) {fos = new FileOutputStream(new File(dir, (count++) + ".part"));fos.write(buf, 0, len);fos.close();}// 将被切割文件的信息保存到prop集合中。prop.setProperty("partcount", count + "");prop.setProperty("filename", file.getName());fos = new FileOutputStream(new File(dir, count + ".properties"));// 将prop集合中的数据存储到文件中。prop.store(fos, "save file info");fos.close();fis.close();}public static void splitFile(File file) throws IOException {// 用读取流关联源文件。FileInputStream fis = new FileInputStream(file);// 定义一个1M的缓冲区。byte[] buf = new byte[SIZE];// 创建目的。FileOutputStream fos = null;int len = 0;int count = 1;File dir = new File("partFiles");if (!dir.exists())dir.mkdirs();while ((len = fis.read(buf)) != -1) {fos = new FileOutputStream(new File(dir, (count++) + ".part"));fos.write(buf, 0, len);}fos.close();fis.close();}}</span></span></span>
3. 自定义过滤文件名类
<span style="font-size:12px;"><span style="font-size:12px;"><span style="font-size:12px;">public class SuffixFilter implements FilenameFilter {private String suffix;public SuffixFilter(String suffix) {super();this.suffix = suffix;}@Overridepublic boolean accept(File dir, String name) {return name.endsWith(suffix);}}</span></span></span>
- Java基础08——I/O流<一>
- Java基础I/O流(一)
- Java基础——I/O流
- java基础——I/O流
- java基础—I/O流
- Java基础——I/O
- Java基础——I/O处理
- Java I/O 技术(十)—— I/O 功能流对象(一)
- 黑马程序员------java基础----I/O流(一)
- 黑马程序员——Java基础--- I/O输入输出流
- Java基础09——I/O流<二>
- Java基础——I/O流简介(待续)
- 黑马程序员—java基础复习—I/O流
- java基础:I/O流
- java基础 - i/o流
- Java I/O 流 基础
- 核心java系列——I/O流详解(一)
- Java I/O流(一)
- 第十六周 程序阅读(2)
- Spring MVC controller和jsp页面传值
- JavaSE8新特性——lambda表达式1
- C++格式化输出,C++输出格式控制
- IDEA 及 Gradle 使用总结
- Java基础08——I/O流<一>
- 编程之美 3.1字符串移位包含的问题
- 【群视频】笔记 - 2015.06.10
- 关于我自己的三个层次
- javase学习之路——面向对象
- javascript--理解Javascript之this关键字
- LeetCode---(152)Maximum Product Subarray
- Exponential families
- 数据结构——二叉树2(c++)