java⽂件不存在就创建_Java中创建并写⽂件的5种⽅式【转载】在Java中有很多的⽅法可以创建⽂件写⽂件,你是否真的认真的总结过?下⾯⼩编就帮⼤家总结⼀下Java中创建⽂件的五种⽅法。
在java中有很多的⽅法可以创建⽂件写⽂件,你是否真的认真的总结过?下⾯笔者就帮⼤家总结⼀下java中创建⽂件的五种⽅法。
实际上不只这5种,通过管道流的排列组合,其实有更多种,但是笔者总结的这五种可以说是最常⽤及最佳实践,
前提⼩知识
以前我在写技术⽂章涉及到“流关闭”、“连接关闭”的时候,经常有⼈留⾔:“还写技术⽂章,写个流都不知道close()”,这种留⾔我遇到过⽆数回!
在本⽂中⼤量的使⽤到了try-with-resources语法,这个语法真的是很久的了,但是的确还有⼩伙伴不知道(知道的⼩伙伴就略过吧)。我还是说⼀下,下⽂中的管道流不是我没close,是⾃动关闭close的。
1. Java wBufferedWriter
java8 提供的newBufferedWriter可以创建⽂件,并向⽂件内写⼊数据。可以通过追加写模式,向⽂件内追加内容。
2. Java 7 Files.write
下⾯的这种⽅式 Files.write ,是笔者推荐的⽅式,语法简单,⽽且底层是使⽤Java NIO实现的。同样提供追加写模式向已经存在的⽂件种追加数据。这种⽅式是实现⽂本⽂件简单读写最⽅便快捷的⽅式。
3. PrintWriter
PrintWriter是⼀个⽐较古⽼的⽂件创建及写⼊⽅式,从JDK1.5就已经存在了,⽐较有特点的是:PrintWriter的println⽅法,可以实现⼀⾏⼀⾏的写⽂件。
4. ateNewFile()
createNewFile()⽅法的功能相对就⽐较纯粹,只是创建⽂件不做⽂件写⼊操作。返回true表⽰⽂件成功,返回 false表⽰⽂件已经存在.可以配合FileWriter 来完成⽂件的写操作。
5.最原始的管道流⽅法
最原始的⽅式就是使⽤管道流嵌套的⽅法,但是笔者觉得这种⽅法历久弥新,使⽤起来⾮常灵活。你想去加上Buffer缓冲,你就嵌套⼀个BufferedWriter,你想去向⽂件中写java对象你就嵌套⼀个ObjectOutputStream。但归根结底要⽤到FileOutputStream。
的初始化,构造⽅法返回后,⼀个对象创建完毕,可以把他的引⽤(地址)发布到外部,在外部就可以使⽤这个引⽤操纵这个对象。
clone 在第⼀步是和 new 相似的,都是分配内存,调⽤ clone ⽅法是,分配的内存和原对象(即调⽤ clone ⽅法的对象)相同,然后再使⽤原对象中对应的各个域,填充新对象的域,填充完成之后,clone ⽅法返回,⼀个新的相同的对象被创建,同样可以把这个新对象的引⽤发布到外部。
3.3 clone 对象的使⽤3.3.1 复制对象和复制引⽤的区别
Person p = new Person(23, "zhang");
Person p1 = p;
System.out.println(p);
System.out.println(p1);
1234
当 Person p1 = p;执⾏之后,是创建了⼀个新的对象吗?⾸先看打印结果:
1.com.itheima.Person@2f9ee1ac
2.com.itheima.Person@2f9ee1ac
12
可以看出,打印的地址值是相同的,既然地址都是相同的,那么肯定是同⼀个对象。p 和 p1 只是引⽤⽽已,他们都指向了⼀个相同的对象Person(23, “zhang”) 。可以把这种现象叫做引⽤的复制。上⾯代码执⾏完成之后,内存中的情景如下图所⽰:
⽽下⾯的代码是真真正正的克隆了⼀个对象。
Person p = new Person(23, "zhang");
Person p1 = (Person) p.clone();
System.out.println(p);
System.out.println(p1);
1234
从打印结果可以看出,两个对象的地址是不同的,也就是说创建了新的对象,⽽不是把原对象的地址赋给了⼀个新的引⽤变量:
1. com.itheima.Person@2f9ee1ac
2. com.itheima.Person@67f1fba0
12
以上代码执⾏完成后,内存中的情景如下图所⽰:
3.3.2 深拷贝和浅拷贝
上⾯的⽰例代码中,Person 中有两个成员变量,分别是 name 和 age, name 是 String 类型, age 是 int 类型。代码⾮常简单,如下所⽰:
public class Person implements Cloneable{
tprivate int age ;
tprivate String name;
public Person(int age, String name) {
ttthis.age = age;
ttthis.name = name;
t}
tpublic Person() {}
tpublic int getAge() {
ttreturn age;
t}
tpublic String getName() {
ttreturn name;
t}
t@Override
tprotected Object clone() throws CloneNotSupportedException {
ttreturn (Person)super.clone();
t}
}
123456789101112131415161718192021222324
由于 age 是基本数据类型,那么对它的拷贝没有什么异议,直接将⼀个 4 字节的整数值拷贝过来就⾏。但是 name是 String 类型的,它只是⼀个引⽤,指向⼀个真正的 String 对象,那么对它的拷贝有两种⽅式:直接将原对象中的 name 的引⽤值拷贝给新对象的 name 字段,或者是根据原 Person 对象中的 name 指向的字符串对象创建⼀个新的相同的字符串对象,将这个新字符串对象的引⽤赋给新拷贝的 Person 对象的 name 字段。这两种拷贝⽅式分别叫做浅拷贝和深拷贝。
下⾯通过代码进⾏验证。如果两个 Person 对象的 name 的地址值相同,说明两个对象的 name 都指向同⼀个String 对象,也就是浅拷贝,⽽如果两个对象的 name 的地址值不同,那么就说明指向不同
的 String 对象,也就是在拷贝 Person 对象的时候,同时拷贝了 name 引⽤的 String 对象,也就是深拷贝。验证代码如下:
Person p = new Person(23, "zhang");
Person p1 = (Person) p.clone();
String result = p.getName() == p1.getName() ? "clone 是浅拷贝的" : "clone 是深拷贝的";
java接口可以创建对象吗System.out.println(result);
1234
打印结果为:
clone 是浅拷贝的
1
所以,clone ⽅法执⾏的是浅拷贝,在编写程序时要注意这个细节。
如何进⾏深拷贝:
由上⼀节的内容可以得出如下结论:如果想要深拷贝⼀个对象,这个对象必须要实现 Cloneable 接⼝,实现 clone⽅法,并且在 clone ⽅法内部,把该对象引⽤的其他对象也要 clone ⼀份,这就要求这个被引⽤的对象必须也要实现Cloneable 接⼝并且实现 clone ⽅法。那么,按照上⾯的结论,实现以下代码 Body 类组合了 Head 类,要想深拷贝Body 类,必须在 Body 类的 clone ⽅法中将 Head 类也要拷贝⼀份。代码如下:
static class Body implements Cloneable{
tpublic Head head;
t
tpublic Body() {}
t
tpublic Body(Head head) {
ttthis.head = head;
t}
t
t@Override
tprotected Object clone() throws CloneNotSupportedException {
ttBody newBody = (Body) super.clone();
ttnewBody.head = (Head) head.clone();
ttreturn newBody;
t}
}
static class Head implements Cloneable{
tpublic Face face;
t
tpublic Head() {}
t
t@Override
tprotected Object clone() throws CloneNotSupportedException {
ttreturn super.clone();
t}
}
public static void main(String[] args) throws CloneNotSupportedException { tBody body = new Body(new Head(new Face()));
tBody body1 = (Body) body.clone();
tSystem.out.println("body == body1 : " + (body == body1) );
tSystem.out.println("body.head == body1.head : " + (body.head == body1.head)); } 12345678910111213141516171819202122232425262728293031323334
打印结果为:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。