转换流
转换流是字符流与字节流之间的桥梁,是为了方便字符流与字节流之间的操作。
当字节流中都是字符时,转成字符流操作更为高效,
例如:能不能使用readLine方法完成键盘录入的一行数据的读取呢,但是readLine是BufferedReader的方法,
而System.in是InputStream的方法,这样就用到了转换流(InputStreamReader)
InputStreamReader是一个字符流,要想转换字节流那就要在构造函数的时候把字节流当参数传入
读取转换流
BfferedReader bufr =
new BufferedReader(new InputStreamReader(System.in));
写入转换流:字符转字节,比如录入的是字符,把它存到硬盘上是字节
BufferedWriter bufw =
new BufferedWriter(new OutputStreamWriter(System.out));
转换流规律:
操作流的时候流对象有很多该用哪个呢?通过三个明确来完成。
1.明确源和目的 有的时候可能只有源或目的,要先明确
源:因为是源所以使用读取流,即 InputStream ,Reader
目的: 写入流 即 OutputStream , Writer
2.明确操作的数据是否为纯文本 即是明确用字节流还是字符流
是:用字符流
不是:用字节流
3.明确设备 就是明确用那个对象,就是看用不用转换流
源设备: 内存 ,硬盘 ,键盘
目的设备:内存 ,硬盘,控制台
然后再确定下需不需要提高效率,就是确定需不需要缓冲流。
例如:
1,将一个文本文件中数据存储到另一个文件中。复制文件。
这个明确了源和目的都有,
源:InputStream Reader
是纯文本吗?是。明所以用字符流 就是Reader
源设备:硬盘 不需要转换流
这时候就可以确定了用 FileReader
是否需要提高效率?是。加入缓冲区 BufferedReader、
FileReader fr = new FileReader("Demo.txt");
BufferedReader bfr = new BufferedReader(fr);
目的:OutputStream Writer
是纯文本吗?是。所以用字符流 Writer.
目的设备:硬盘 不需要转换流。
所以就可以确定用 FileWriter了。
是否需要提高效率?是。加入缓冲区 BufferedWriter
FileWriter fw = new FileWriter();
BufferedWriter bfw = new BufferedWriter(fw);
2,需求:将键盘录入的数据保存到一个文件中。
明确1这个既有源也有目的
源: InputStream Reader
是否为纯文本?是,键盘录入的也是字符,用Reader
源设备:键盘。对应的对象是 System.in。这时就想了上面不是明确了用Reader了吗,但是
System.in是字节流啊,所以既然明确了用Reader这时就需要用转换流了InputStreamReader。
需要提高效率吗?需要。所以要用BufferedReader。
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader bfr = new BufferedReader(isr);
目的:OutputStream Writer
是否为纯文本?是, 用Writer
目的设备:一个文件文件 在硬盘 不需要转换流,可以确定用FileWriter
FileWriter fw = new FileWriter("Demo.txt");
需要提高效率吗?需要。
BufferedWriter bufw = new BufferedWriter(fw);
--------------------------------------------------------------------------------------------
扩展:想要把录入的数据按照指定的编码表(utf-8),将数据存到文件中。
源和上面的一样,不变。
目的:OutputStream Writer
是否为纯文本?是,Writer
目的设备:硬盘 一个文件 用 FileWriter
FileWriter是按默认的编码(GBK)存的。但是要求按照指定的编码(utf-8)存数据
而指定编码表只有转换流能制定,所以使用的对象是OutputStreamWriter,而转换流
又要接收一个字节流,而且该字节流还能操作文件,所以就是 FileOutputStream
需要提高效率吗?需要。所以要用到BufferedReader
OutputStreamWriter osw =
new OutputStreamWriter(new FileOutputStream("Demo.txt"),"UTF-8");
所以,记住。转换流什么使用。字符和字节之间的桥梁,通常,涉及到字符编码转换时,
需要用到转换流。
改变标准输入输出流设备:
系统默认的标准输入输出设备是 System.in 和 System.out
但是可以通过System类中setIn,setOut方法对默认设备进行改变。
System.setIn(new FileInputStream(“1.txt”));//将源改成文件1.txt。
System.setOut(new FileOutputStream(“2.txt”));//将目的改成文件2.txt
---------------------------------------------------------------------------------------------------------------------------------
File类
流在操作的只有数据,而数据最明显的体现形式就是文件,文件又包含了很多的属性和行为信息,
比如说前缀名、扩展名、文件自己的大小时间等,所以文件是一个复杂的事物而这个事物有很多,
所以java就对文件这类的事物进行了描述,也把它封装成了对象,方面了我们对文件或文件夹的
属性进行操作。而File类的对象也主要用来获取文件本身的一些信息,如文件大小权限等,不涉
及对文件的读写操作。
查看API知道java提供了三种创建方法来生成一个文件对象。
(1)根据参数指定的文件路径创建一个File文件对象,就是把某个文件封装成对象
File file1 = new File("D:\\abc\\123.txt");
(2)根据给定的目录创建一个File实体对象,其中"d:\\abc"为目录,"123.txt"为文件的名称
File file2 = new File("D:\\abc","123.txt");
(3)可以根据已知的目录文件对象File创建一个新的File实体对象
File d = new File("D:\\abc");
File file3 = new File(d,"123.txt");
File类所提供的方法中,有的是针对文件的处理,有的是针对目录的处理,可以通过一些方法来
判断文件是否存在以及文件的相对路径和绝对路径等,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()
部分代码:
class FileDemo { public static void main(String[] args) throws IOException { File f = new File("abc.txt");//把文件封装成对象 sop(f.createNewFile());//创建一个文件创建成功返回true,如果已存在创建不成功,返回false File f = new File("abc"); sop(f.mkdir());//创建一个目录,mkdirs能创建多级目录 //在判断文件对象是否是文件或者目录时,一定要先判断该文件对象封装的内容是否存在 isexists();//因为封装了一个文件对象,如果没创建的话,系统里就没有的所以要先判断下。 isFile();//判断你创建的是否为文件 isDirectory();//判断是否为目录 File f = new File("abc\\abc.txt"); getParent();//获取绝对路径的文件父目录,你创建时是相对路径会返回null //如果相对路径中有上一层目录那么该目录就是返回结果。如上返回父目录abc } public static void sop(Object obj) { System.out.println(obj); } }文件列表:
listRoots();//能列出我们机器里面有效的盘符,它是一个静态方法,返回的是File数组
String[] list();//返回值类型是是String数组,
File f = new File("d:\\");
Stringp[] names = f.list();//打印的是d盘下所有文件和文件夹的名称,所以返回的是字符串数组
//但是要确定调用list方法的File对象必须是封装了一个目录,并且该目录还必须存在
for(String name : names)//不然你封装了一个文件对象,那它返回的数组就为null,那就不能遍历数组了
{
System.out.println(name);
}
File[] files = f.listFile();
for(String file : files)
{
System.out.println(file.getName()+"::"+file.length());//因为返回的是文件对象仍然能调用方法
}
----------------------------------------------------------------------------------------------------------------------------------
递归:在遍历文件夹的时候,遍历的结果中仍有文件夹,这事是不是还要在遍历一次啊,比如说,你打开d盘
里面是不是有很多文件夹啊,然后是不是就要点开看看啊,然后里面还有文件夹是不是还要打开?这
样是不是在重复一个操作,就是遍历文件夹里的元素,里面有文件夹的话就再遍历....这样我们在
写代码的时候是不是再重复用同一个方法,就是用一个方法遍历文件夹,如果里面有文件夹的话,就在
调用本方法。也就是函数自身调用自身。这种编程手法就是递归。
部分代码:
class FileDemo { public static void main(String[] args) throws IOException { File dir = new File("f:\\javademo"); showDir(dir); } public static void showDir(File dir) { File[] files = dir.listFiles(); for(int x=0; x { if(files[x].isDirectory())//判断,如果便利中碰到文件夹 showDir(files[x]);//就再调用此方法进行遍历 else System.out.println(files[x]); } } }递归要注意:
1,限定条件。没条件限定的话,函数里面又调用它自身不就相当于死循环啦。
2,要注意递归的次数。尽量避免内存溢出。每次递归都会在栈内存中开辟空间,不限定的话会内存溢出
------------------------------------------------------------------------------------------------------------------------------------
Properties类:
Properties是hashtable的子类。一个可以将键值进行持久化存储的对象。
也就是说它具备map集合的特点。而且它里面存储的键值对都是字符串。
是集合中和IO技术相结合的集合容器。
该对象的特点:可以用于键值对形式的配置文件。
那么在加载数据时,需要数据有固定格式:键=值。
特点:
1:可以持久化存储数据。
2:键值都是字符串。
3:一般用于配置文件。
|-- load():将流中的数据加载进集合。
原理:其实就是将读取流和指定文件相关联,并读取一行数据,因为数据是规则的key=value,所以获
取一行后,通过 = 对该行数据进行切割,左边就是键,右边就是值,将键、值存储到properties集合中。
|-- store():写入各个项后,刷新输出流。
|-- list():将集合的键值数据列出到指定的目的地。
--------------------------------------------------------------------------------------------------------------------------------
IO包中的其他类:
打印流
PrintWriter与PrintStream 可以直接操作输入流和文件。该流提供了打印方法,可以将各种数据类
型的数据都原样打印。
字节打印流:PrintStream
构造函数可以接收的参数类型:
1,file对象。File
2,字符串路径。String
3,字节输出流。OutputStream
字符打印流:PrintWriter
构造函数可以接收的参数类型:
1,file对象。File
2,字符串路径。String
3,字节输出流。OutputStream
4,字符输出流,Writer。
-----------------------------------------------------------------------------------------------------------------------------------
序列流
SequenceInputStream 对多个流进行合并。它的构造函数接收的是两个输入流,或者是接收一个输
入流的枚举。
比如说要把三个文件的内容复制到另一个文件中,是不是要一个一个的重复Copy文件的那个动作啊,
就是每复制一个文件都要创建一个写入流和输出流,然后再进行读写操作,复制三个文件是不是就
要重复三次啊,并且创建目的文件的时候还要写成可续写格式,不然就会被覆盖掉,而序列流就解
决了这个问题,他可以把多个流合并在一起,然后再进行其他操作。
//把三个文件复制到另一个文件中 部分代码:
public static void main(String[] args) throws IOException { //枚举只有list集合里的vector有所以要创建一个集合来装输入流 Vector v = new Vector(); //把三个文件的读取流对象添加到集合里 v.add(new FileInputStream("d:\\1.txt")); v.add(new FileInputStream("d:\\2.txt")); v.add(new FileInputStream("d:\\3.txt")); //获取集合的枚举Enumeration Enumeration en = v.elements(); //将输入流的枚举传给序列流,之后操作这个流就行了 SequenceInputStream sis = new SequenceInputStream(en); //创建一个写入流再然后进行频繁的读写就行了 FileOutputStream fos = new FileOutputStream("c:\\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(); } 能合并就能切割://切割一图片 public static void spilt() throws IOException { FileInputStream fis = new FileInputStream("E:\\0.PNG"); FileOutputStream fos = null; byte[] arr = new byte[1024*1024]; int len = 0; int x=1; //每一次循环是不是都创建了一个流就是创建了一个文件啊? while((len=fis.read(arr))!=-1) { fos=new FileOutputStream("E:\\spilte\\"+(x++)+".part"); fos.write(arr,0,len); fos.close(); } fis.close(); }------------------------------------------------------------------------------------------------------------------------------
操作对象的流
ObjectInputStream与ObjectOutputStream 被操作的对象需要实现Serializable (标记接口);
流是可以操作数据的,现在数据被封装成对象了,我们知道对象是存放在堆内存中的,用完之后
就成了垃圾了,一被清理之后这个对象是不是就不存在了?而现在讲的这个流就可以操作对象,
把这个对象的数据存放在硬盘上,对象里都封装了一些数据,那这些数据是不是就随着对象也存到
了硬盘上啦?这样的话即使这个程序结束了对象被清理了,我们是不是仍然能够获得这个对象里的
数据啊,因为它已经被存放到硬盘上了。
另外操作的那个对象的类要能被序列化,某个类要想能被序列化,就得实现java.io.Serializable 接口。
部分代码:
ObjectOutputStream的目的是把对象和流相结合,是不是先把对先把流当参数传给它啊,所
以ObjectOutputStream在构造函数时一定要接收个流,什么流呢?就是把对象怎么着的流?也
就是目的。
//既然要把对象写进文件那就要创建一个写入流
FileOutputStream fos = new FileOutputStream("t.tmp");
//把写入流当参数传给ObjectOutputStream
ObjectOutputStream oos = new ObjectOutputStream(fos);
//操作的这类person对象的类要实现Serializable接口
oos.writeObject(new Person());//将指定对象写入ObjectOutputStream。
oos.writeInt(12345);
oos.close();
-----------------------------------------------------------------------------------------------------------------------------------------
管道流
PipedInputStream和PipedOutputStream输入输出可以直接进行连接,通过结合线程使用。
管道输入流应该连接到管道输出流;管道输入流提供要写入管道输出流的所有数据字节。通常,数据
由某个线程从 PipedInputStream 对象读取,并由其他线程将其写入到相应的 PipedOutputStream。
不建议对这两个对象尝试使用单个线程,因为这样可能死锁线程。管道输入流包含一个缓冲区,可在
缓冲区限定的范围内将读操作和写操作分离开。如果向连接管道输出流提供数据字节的线程不再存在,
则认为该管道已损坏。
-------------------------------------------------------------------------------------------------------------------------------------
RandomAccessFile类
该类不是算是IO体系中子类。而是直接继承自Object。但是它是IO包中成员。因为它具备读和写
功能。内部封装了一个数组,而且通过指针对数组的元素进行操作。可以通过getFilePointer获
取指针位置,同时可以通过seek改变指针的位置。
其实完成读写的原理就是内部封装了字节输入流和输出流。
通过构造函数可以看出,该类只能操作文件。而且操作文件还有模式:只读r,,读写rw等。
如果模式为只读 r。不会创建文件。会去读取一个已存在文件,如果该文件不存在,则会出现异常。
如果模式rw。操作的文件不存在,会自动创建。如果存则不会覆盖。
java语言提供了一个RandomAccessFile类来处理对一部分文件的输入/输出。RandomAccessFile类
创建的流于前面的输入输出流不一样,它既不是输入流InputStream的子类也不是输出流类OutputS-
-tream的子类,但是RandomAccessFile类创建的流的指向既可以做为源也可以作为目的,换句话说
如果相对一个文件进行读取操作时,可以创建一个指向该文件的RandomAccessFile流,这样既可以
从这个流中读取文件的数据,也可以从这个流中写入数据到文件。
可以用以下两种方式打开一个随机存取文件:
字符编码
字符流的出现为了方便操作字符。更重要是的加入了编码转换。
通过子类转换流来完成。 InputStreamReader OutputStreamWriter
在两个对象进行构造的时候可以加入字符 集。
编码:字符串变成字节数组。
解码:字节数组变成字符串。
String-->byte[]; str.getBytes(charsetName);
byte[] -->String: new String(byte[],charsetName);
部分代码:
class EncodeDemo { public static void main(String[] args)throws Exception { String s = "哈哈"; byte[] b1 = s.getBytes("GBK"); System.out.println(Arrays.toString(b1)); String s1 = new String(b1,"utf-8"); System.out.println("s1="+s1); //对s1进行iso8859-1编码。 byte[] b2 = s1.getBytes("utf-8"); System.out.println(Arrays.toString(b2)); String s2 = new String(b2,"gbk"); System.out.println("s2="+s2); } }
相关推荐
黑马程序员_毕向东_Java基础视频教程第18天-14-IO流(拷贝文本文件图例).zip
黑马程序员__移动商城项目实战 包括黑马程序员乐淘商城实战和慕课React+Antd
公式指标,黑马起爆,有助于判断什么时候可以入手
黑马程序员_毕向东_Java基础视频教程第18天-09-IO流(文件的续写)
JavaWeb是Java编程领域中的一个重要组成部分,主要涉及Web应用程序的开发和实现。黑马程序员是一家知名的IT教育机构,他们提供的Javaweb教材源码是为了帮助学员深入理解和实践Web开发技术。下面将详细介绍JavaWeb的...
本教程《黑马程序员_毕向东_Java基础视频教程第18天-13-IO流(拷贝文本文件)》专注于讲解如何利用IO流来实现文本文件的复制操作。这个过程涉及到了对文件读取、数据缓冲以及写入等基础知识,对于初学者来说是理解和...
本文将深入探讨2016年黑马程序员发布的Hibernate框架开发课程的第二天内容。Hibernate,一个强大的Java持久化框架,简化了数据库操作,为开发者提供了对象关系映射(ORM)解决方案。在Day02的学习中,我们将重点关注...
在本教程“黑马程序员_毕向东_Java基础视频教程第18天-11-IO流(文本文件读取方式二)”中,主讲人毕向东将深入讲解如何使用Java有效地读取文本文件,特别是第二种常用的方法。以下是关于Java IO流和文本文件读取的...
存放黑马项目源代码_heima
Java的输入/输出(IO)系统是编程中的一个重要部分,特别是在开发服务器端应用程序、文件处理以及数据传输场景中。"IO-黑马程序员Java学习笔记"这个压缩包包含了关于Java IO的详细教程,可以帮助我们深入理解这个...
标题中的“heima_ugo_xiaochengxu_黑马训练营_微信小程序_小程序支付_VantWeapp商城”揭示了这是一个关于微信小程序开发的项目,由黑马训练营提供教学支持,特别关注了商城功能、微信登录和微信支付的集成,并且使用...
《黑马程序员匠心之作 C++教程_第2阶段实战-通讯录管理讲义》是一份针对C++初学者精心编写的教学材料,旨在帮助学习者掌握C++编程语言的基础知识,并通过实际的通讯录管理系统项目来提升编程技能。这份讲义以简洁...
黑马程序员_张孝祥_Java多线程与并发库,老师讲的非常仔细,老师很有耐心.欢迎大家下载学习.
"黑马旅游网项目_java_web_基础" 这个标题表明这是一个关于Java Web开发的项目,特别强调了基础部分。这意味着它可能是针对初学者或中级开发者的一个教学项目,旨在帮助他们掌握Java Web开发的基础知识。在这个项目...
在这个“黑马程序员_毕向东_Java基础视频教程第18天-12-IO流(文本文件读取练习)”中,毕向东老师将深入讲解如何使用Java IO流来读取文本文件。Java IO流提供了多种类和方法,使得开发者可以灵活高效地处理输入和输出...
《黑马程序员_从零开始征服Android之旅(第二季)源码和笔记(上)》是一部针对初学者的全面Android开发教程,旨在帮助学员系统地掌握Android应用开发的基础知识和实战技巧。通过本教程的学习,你可以从理论出发,...
【标题】"传智播客_黑马_品优购_2018"指的是一个由传智播客和黑马程序员联合推出的2018年品优购相关的IT培训课程资源。这个课程可能涵盖了电子商务、互联网产品开发、运营等多个方面,旨在帮助学员掌握最新的技术和...
本资料包“Java-IO流高级-例题 & 例题源码 & PPT教学文档(黑马程序员详细版).rar”提供了一个深入学习Java IO流的全面资源,包含实例题目、源代码以及PPT教学材料,适合对Java IO有进阶需求的开发者。 1. **Java ...
【青橙电商前台开发02】课程主要涵盖了电商网站前端开发的相关知识,是黑马教育机构推出的borns8e系列课程之一。在这个课程中,你将深入学习如何构建一个功能完善的电商平台前端界面,提升你的前端开发技能。以下是...
【标题】"01_黑马程序员_张孝祥_Java基础加强_课程价值与目标介绍.zip" 提供的是一门由黑马程序员机构推出的Java基础强化课程,由讲师张孝祥主讲,旨在深入讲解Java编程的基础知识并进行能力提升。 【描述】中提到...