1文件流
1.1什么是文件流
文件可以认为是相关记录(二进制)或者放在一起的数据的集合,目录是比较特殊的文件,目录中还可以存放文件和目
1.2文件的本质
文件的本质:二进制数据 00000001 0000010
就是路径的抽象,http://localhost:8080/text/1.jsp D://a//1.txt
录。
1.3Eclipse快捷使用
Love
Ctrl+shifr+左右:选中一个单词
Shift+左右:选中一个字母
Ctrl+D:删除一行
Ctrl+alt+上下:向上或向下复制一行
Shift_tab:选中的代码整体向前
Tab:选中的代码整体向后
1.4文件使用的类及构造器
Java.io.File
File只能操作文件的属性而不能操作本身及内容,假如涉及到文件的转移,文件的内容的获取和设定都需要借助于流。
new File("D://1.txt");
new File("http://....");
new File(new File("D://"), "1.txt");
new File("D://", "1.txt");
1.5文件常见的方法
File file=new File("D://1.txt");
file.canExecute();//是否是可执行文件true/false
file.canRead();//是否是可读文件true/false
file.canWrite();//是否是可写文件true/false
// file.createNewFile();//创建文件,特指不包含目录
file.delete();//删除文件
file.deleteOnExit();//退出jvm删除临时文件
// file.createTempFile(prefix, suffix);//创建临时文件
file.exists();//文件是否存在true/false
file.isFile();//是不是文件,特指不包含目录
file.isDirectory();//是不是目录
file.isHidden();//是不是隐藏文件
file.listRoots();//通过静态方法获取当前的盘符
file.mkdir();//创建目录
file.list();//得到当前目录下的所有文件和目录
// file.list(FilterNamefilter);//文件过虑器
file.lastModified();//文件的最后修改时间
file.length();//文件中的长度--字节数
file.getName();//得到文件的名字
1.6文件过滤器
@Test
public void testFileFilter(){
File file=new File("D://");
//得到D盘符下的所有文件
String []files=file.list(new MyFileFilter());
for (int i = 0; i < files.length; i++) {
System.out.println(files[i]);
}
}
class MyFileFilter implements FilenameFilter{
public boolean accept(File dir, String name) {
return name.endsWith(".txt");
}
}
1.7文件广度优先遍历
队列:先进先出,后进后出
打印机:打印内容是按照顺序打印,谁先提交任务,谁就先出来。
使用场合:查询当前有哪些化妆品及品牌
//文件的广度优先遍历
public void testFileWidth(File dir){
//创建队列
Queue<File> qu=new LinkedList<File>();
//跟目录入队
qu.offer(dir);
while(!qu.isEmpty()){
//出队
File file=qu.poll();
if(file.isFile()){
System.out.println("=======文件======"+file.getName());
}else{
System.out.println("=======目录======"+file.getName());
//得到子目录中的文件和目录,并需要判断是不是文件和目录
//回调
File []fs=file.listFiles();
for (int j = 0; j < fs.length; j++) {
qu.offer(fs[j]);
}
}
}
}
1.8得到文件中的内容
@Test
//得到文件中的内容
public void getFileContent() throws Exception{
File file=new File("D://1.txt");
InputStream is=new FileInputStream(file);
Reader reader=new InputStreamReader(is);
int temp=-1;
while((temp=reader.read())!=-1){
System.out.print((char)temp);
}
}
1.9书写内容到文件中
@Test
//将对应的内容写入文件中
public void setFileContent() throws Exception{
File file=new File("D://1.txt");
OutputStream os=new FileOutputStream(file);
Writer writer=new OutputStreamWriter(os);
String str="我爱妈妈!";
writer.write(str);
writer.flush();
}
2.序列化
2.1为什么要序列化
序列化的本质:流化 将数据转化成二进制字节码文件,网络中传输
序列化有固定的流化对象:针对对象的流化和反流化
文件需要在网络中传输,而网络中只接受二进制字节码文件。
序列化就是可以使数据形态发生变化的工具。
2.2什么是序列化
序列化是将一个对象的状态(属性的值)保存起来,然后在适当的时候获得。
序列化分为两部分:序列化和反序列化。
序列化是这个过程的第一步,将数据分解成字节流,一般存储在文件中或在网络上传输。反序列化就是打开字节流并重构对象。对象序列化不仅要将基本数据类型转换成字节表示,于是还有恢复数据。恢复数据要求有恢复数据的对象实例。
2.3序列化的本质
本质:流化,是一个过程,由java虚拟机完成,不由程序员完成。
2.4对象流
能够输入和输出对象的流称为对象流,通过对象流可以将实现了Serializable接口的对象写进内存、磁盘或网络介质中,此过程称为对象的序列化过程,也可以通过对象流将内存,磁盘和网络中的字节流读入类的实例中,此过程称为对象的重构或反序列化。
对象的序列化仅仅只针对对象的实例变量值进行保存(不包含访问权限、变量类型、和其他修饰符),所有的方法和静态变量将不会被序列化。
2.5序列化实现
对象序列化要求对象实现序列化接口
public class Student implements Serializable{}
2.5.1序列化
@Test
public void serialize() throws Exception{
try {
Student stu=new Student("1001","十一郎","男","30","安徽合肥","1001");
OutputStream os=new FileOutputStream("E:\\1.txt");
//对象输出流
ObjectOutputStream oos=new ObjectOutputStream(os);
oos.writeObject(stu);
oos.flush();
oos.close();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
2.5.2反序列化
@Test
public void deserialize(){
Student stu=null;
try {
InputStream is=new FileInputStream("E:\\1.txt");
ObjectInputStream oos=new ObjectInputStream(is);
stu=(Student)oos.readObject();
System.out.println(stu.getStu_name());
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
2.6序列化 ID 的问题
private static final long serialVersionUID = -1384354585029029786L;
情景:两个平台使用序列化进行数据传输,反序列化是否成功不经取决于反序列化本身还取决于serialVersionUID。
总结:
其实序列化的作用是能转化成Byte流,然后又能反序列化成原始的类。能在网络进行传输,也可以保存在磁盘中,有了SUID之后,那么如果序列化的类已经保存了在本地中,中途你更改了类后,SUID变了,那么反序列化的时候就不会变成原始的类了,还会抛异常,主要就是用于版本控制。
3.xml文件读写
3.1什么是xml
Xml出现的意义其实与JSON字符串的意义相似。
几乎所有的语言都支持json字符串的创建和解析—实现跨平台快语言。
XML是由万维网协议(w3c)推出的新一代数据交换的标准。
XML:Extensible Markup Language一种扩展性标示语言。一种能让用户自己创造标
示的语言,可以存储数据和共享数据。
优势:一种结构化文档和通用且适应性强的格式,它不仅仅适用于web,而且可以被用于任何的地方。
标记:计算机所能理解的信息符号。
什么是可扩展标记语言?
可扩展标记语言是一种很像超文本标记语言的标记语言。
<aa></aa>
它的设计宗旨是传输数据,而不是显示数据。
它的标签没有被预定义,需要自行定义标签。
它被设计具有自我描述。
对此最好的描述:独立于软件和硬件的信息传输工具。
独立于软件和硬件的数据交换格式,功能类似于json
3.2常见的xml解析工具
DOM4J性能最好,连Sun的JAXM也在用DOM4J。目前许多开源项目中大量采用DOM4J,例如大名鼎鼎的Hibernate也用DOM4J来读取XML配置文件。如果不考虑可移植性,那就采用DOM4J。
DOM4J;是所有xml解析中综合性能最优的产品。
JDOM和DOM在性能测试时表现不佳,在测试10M文档时内存溢出。在小文档情况下还值得考虑使用DOM和JDOM。虽然JDOM的开发者已经说明他们期望在正式发行版前专注性能问题,但是从性能观点来看,它确实没有值得推荐之处。另外,DOM仍是一个非常好的选择。DOM实现广泛应用于多种编程语言。它还是许多其它与XML相关的标准的基础,因为它正式获得W3C推荐(与基于非标准的Java模型相对),所以在某些类型的项目中可能也需要它(如在JavaScript中使用DOM)。
JDOM和DOM:基于树模型,在运行的时候会将xml文件中的所有内容都加入到内存中,对内存的消耗大。适用于小文档。
SAX表现较好,这要依赖于它特定的解析方式-事件驱动。一个SAX检测即将到来的XML流,但并没有载入到内存(当然当XML流被读入时,会有部分文档暂时隐藏在内存中)。
SAX:不支持回溯,基于事件驱动
3.3快速掌握XML的创建和解析核心类
SAXReader:读取xml的核心类
Document:xml文档类
创建文档中的内容:
Document document = DocumentHelper.createDocument();
写入文档的核心类:
writer = new XMLWriter( out, format );
3.4读取特定的xml中的内容
getName():得到当前的元素名称
getText():得到元素中间的内容
attributeValue("sex"):得到元素对应的属性的值
@Test
public void parseXMLTest() throws Exception{
//创建核心解析器
SAXReader reader=new SAXReader();
File file=new File("D://1.xml");
Document doc=reader.read(file);
//得到xml的跟节点
Element root= doc.getRootElement();
//通过跟节点得到子节点
List<Element> elements= root.elements();
//遍历得到所有的自己点的属性和值
for (Element eles:elements) {
System.out.println(eles.attributeValue("name"));
}
}
3.5将对应的集合或对象创建成xml文件
//创建xml
@Test
public void createXML() throws Exception{
Document doc=DocumentHelper.createDocument();
Element root= doc.addElement("Students");
root.addElement("student")
.addAttribute("id", "0001")
.addAttribute("name", "李寻欢")
.addText("小李飞刀寻欢喜欢林诗音。");
root.addElement("student")
.addAttribute("id", "0002")
.addAttribute("name", "阿飞")
.addText("此时一手好剑法。");
File file=new File("D://abcd");
if(!file.exists()){
file.mkdir();
}
OutputStream out=new FileOutputStream(file+"//"+"2.xml");
OutputFormat format=OutputFormat.createPrettyPrint();
format.setEncoding("GBK");
XMLWriter writer=new XMLWriter(out, format);
writer.write(doc);
writer.flush();
writer.close();
out.close();
}
3.6修改xml中指定的参数
//修改xml中的参数
@Test
public void updxml() throws Exception{
//创建核心解析器
SAXReader reader=new SAXReader();
File file=new File("D://abcd//2.xml");
Document doc=reader.read(file);
//得到xml的跟节点
Element root= doc.getRootElement();
//通过跟节点得到子节点
List<Element> elements= root.elements();
//遍历得到所有的自己点的属性和值
for (Element eles:elements) {
if(eles.attributeValue("id").equals("0001")){
System.out.println("====1====");
Attribute attr= eles.attribute("name");
attr.setValue("寻欢作乐");
}
}
OutputStream out=new FileOutputStream(file);
OutputFormat format=OutputFormat.createPrettyPrint();
format.setEncoding("GBK");
XMLWriter writer=new XMLWriter(out, format);
writer.write(doc);
writer.flush();
writer.close();
out.close();
}
3.7模拟服务器解析web.xml文件实例化servlet的案例
Class.forName("com.mysql.jdbc.Driver");实际上就是实例化Driver类。
Class.forName=new
String url=”add.do”; 通过add.do去找到对应的全限定类名
//解析web.xml实例化对应的类
@Test
public void parseWebXML() throws Exception{
String url="/add.do";
SAXReader reader=new SAXReader();
File file=new File(System.getProperty("user.dir")+"//src//web.xml");
Document doc=reader.read(file);
//得到xml的跟节点
Element root= doc.getRootElement();
//通过跟节点得到子节点
List<Element> elements= root.elements();
String servletName="";
//遍历子元素
/*for (Element eles:elements) {
//找到诸多的servlet-mapping中哪一个url-pattern的值与上面的url相等
if(eles.getName().equals("servlet-mapping")){
//使用ElementText判断servlet-mapping下的子元素的值是否匹配
if(eles.elementText("url-pattern").equals(url)){
//假如上面成立,说明就是这个servlet-mapping
servletName=eles.elementText("servlet-name");
}
}
}*/
for (Element eles:elements) {
if(eles.getName().equals("servlet-mapping")){
//得到当前的servlet-mapping元素下的子元素(serlvet-name,url-pattern)
List<Element> urlpattern=eles.elements();
for (Element e:urlpattern) {//用来遍历一个servlet-mapping中的多个url-pattern
if(e.getName().equals("url-pattern")){
if(e.getText().equals(url)){//第一次/login2.do
servletName=eles.elementText("servlet-name");
}
}
}
}
}
String servletClass="";
for (Element eles:elements) {
//找到诸多的servlet-mapping中哪一个url-pattern的值与上面的url相等
if(eles.getName().equals("servlet")){
//使用ElementText判断servlet-mapping下的子元素的值是否匹配
if(eles.elementText("servlet-name").equals(servletName)){
//假如上面成立,说明就是这个servlet-mapping
servletClass=eles.elementText("servlet-class");
}
}
}
Class.forName(servletClass).newInstance();
}
今天的分享就到这里!!!!!!!!