Day14基础不牢地动山摇-Java基础

目录
  • 1、定时器
  • 2、UUID类
  • 3、Base64加密处理
    • 加密处理
    • 多次加密
  • 4、ThreadLocal类
  • 5、IO—File类
    • 5.1 基本操作
    • 5.2 取得文件信息
    • 5.3 综合案例:目录列表
  • 6、IO— 字节流与字符流
    • 6.1 字节输出流:OutputStream
    • 6.2 字节输入流:InputStream
    • 6.3 字符输出流:Writer
    • 6.4 字符输入流:Reader
    • 6.5 字节流与字符流区别
  • 7、转换流

1、定时器

推动整个计算机硬件的发展的核心关键性技术就是时钟。所以在企业开发中定时操作往往成为开发重点。而在JDK本身也支持这种定时调度的处理操作,这种操作不会直接使用。还是和多线程有关。

  • 如果想要定时调度处理操作,需要两个类
  • 定时调度任务:java.util.TimerTask定时调度操作:java.util.Timer
package com.day14.demo;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

class MyTask extends TimerTask{

	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println(new SimpleDateFormat("YYYY-MM-dd HH:mm:ss.SSS").format(new Date()));
	}

}
public class TaskDemo {
	public static void main(String[] args) {
		Timer timer = new Timer();
		timer.schedule(new MyTask(), 1000,2000);
	}
}

2、UUID类

UUID类是根据你当前的地址还有时间戳自动生成一个几乎不会重复的字符串。

package com.day14.demo;

import java.util.UUID;

public class UUIDDemo {
	public static void main(String[] args) {
		UUID uuid = UUID.randomUUID();
		System.out.println(uuid);
	}
}

以后再文件上传等类似的操作中通过UUID类来进行简单的文件名称,以防止重名的问题。

3、Base64加密处理

Base64是一种数据加密算法,使用整个算法可以使我们的数据进行安全处理。如果要想进行加密处理可以使用两个:加密器、解密器。

加密处理

package com.day14.demo;

import java.util.Base64;

public class Base64Demo {
	public static void main(String[] args) {
		String msg = "123456";
		String emsg = Base64.getEncoder().encodeToString(msg.getBytes());
		System.out.println("加密:" + emsg);
		byte[] decode = Base64.getDecoder().decode(emsg);
		System.out.println("解密:" + new String(decode));
	}
}

多次加密

package com.day14.demo;

import java.util.Base64;

public class Base64Demo {
	public static void main(String[] args) {
		String msg = encode("123456");
		String emsg = encode(encode(encode(msg)));
		System.out.println("加密:" + emsg);
		byte[] decode = Base64.getDecoder().decode(emsg);
		System.out.println("解密:" + new String(decode));
	}
	public static String encode(String code){
		return Base64.getEncoder().encodeToString(code.getBytes());
	}
}

还有一个做法就是种子树

package com.day14.demo;

import java.util.Base64;

public class Base64Demo {
	public static void main(String[] args) {
		String sed = encode("zsr--rsz");
		String msg = "123456"+sed;
		String emsg = encode(msg);
		System.out.println("加密:" + emsg);
		byte[] decode = Base64.getDecoder().decode(emsg);
		System.out.println("解密:" + new String(decode));
	}
	public static String encode(String code){
		return Base64.getEncoder().encodeToString(code.getBytes());
	}
}

必须保证长度,以后的开发将Base64和MD5一起开发,长度是32位。

4、ThreadLocal类

TheadLocal类不继承Thread类,也不实现Runable接口,ThreadLocal类为每一个线程都维护了自己独有的变量拷贝。每个线程都拥有自己独立的变量。

ThreadLocal采用了“以空间换时间”的方式:访问并行化,对象独享化。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。

ThreadLocal的实现是这样的:每个Thread维护了一个ThreadLocalMap映射表,这个映射表的key是ThreadLocal实例本身。Value是真正需要存储的变量。也就是说,ThreadLocal本身并不存储值,它只是作为一个key来让线程从ThreadLocalMap获取value。注意,ThreadLocalMap是使用ThreadLocal的弱引用作为key的,弱引用的对象在GC时会被回收。

通过给方法传递参数,调用两个线程输出不同的信息

package com.day14.demo;
class Message{
	private String note;

	public String getNote() {
		return note;
	}

	public void setNote(String note) {
		this.note = note;
	};
}
class GetMessage{
	public void print(Message msg){
		System.out.println(Thread.currentThread().getName() + msg.getNote());
	}
}
public class ThreadLocalDemo {
	public static void main(String[] args) {
		new Thread(()->{
			Message message = new Message();
			message.setNote("Hello,world!!");
			new GetMessage().print(message);
		},"用户A").start();

		new Thread(()->{
			Message message = new Message();
			message.setNote("Hello,world!!zsr");
			new GetMessage().print(message);
		},"用户B").start();
	}
}

但是我现在的需求是不希望通过传递传输给GetMessage的print方法,还希望实现相同的功能。

package com.day14.demo;
class Message{
	private String note;

	public String getNote() {
		return note;
	}

	public void setNote(String note) {
		this.note = note;
	};
}
class GetMessage{
	public void print(Message msg){
		System.out.println(Thread.currentThread().getName() + msg.getNote());
	}
}
public class ThreadLocalDemo {
	public static void main(String[] args) {
		new Thread(()->{
			Message message = new Message();
			message.setNote("Hello,world!!");
			new GetMessage().print(message);
		},"用户A").start();

		new Thread(()->{
			Message message = new Message();
			message.setNote("Hello,world!!zsr");
			new GetMessage().print(message);
		},"用户B").start();
	}
}

我们发现两个线程的内容并没有同步输出,所以我们会想到通过ThreadLocal类来解决此数据不同步的问题。

public class ThreadLocal<T> extends Object

这个类里面有几个重要的方法:

  • 取得数据:public T get()
  • 存放数据:public void set(T value)
  • 删除数据:public void remove()

利用ThreadLocal来解决当前我问题

package com.day14.demo;
class Message{
	private String note;

	public String getNote() {
		return note;
	}

	public void setNote(String note) {
		this.note = note;
	};
}
class GetMessage{
	public void print(){
		System.out.println(Thread.currentThread().getName() + MyUtil.get().getNote());
	}
}
class MyUtil{
	private static ThreadLocal<Message> tl = new ThreadLocal<Message>();
	public static void set(Message msg){
		tl.set(msg);
	}
	public static Message get(){
		return tl.get();
	}
}
public class ThreadLocalDemo {
	public static void main(String[] args) {
		new Thread(()->{
			Message msg = new Message();
			msg.setNote("Hello,world!!");
			MyUtil.set(msg);
			new GetMessage().print();
		},"用户A").start();

		new Thread(()->{
			Message msg = new Message();
			msg.setNote("Hello,world!!zsr");
			MyUtil.set(msg);
			new GetMessage().print();
		},"用户B").start();
	}
}

这样我们就解决了数据不同步的问题了。

5、IO—File类

5.1 基本操作

如果要想学好IO,必须要清楚抽象类、IO的操作部分掌握两个代码模型。IO的核心组成五个类(File、OutputStream、InputStream、Writer、Reader)一个接口(Serializable)。

再java.io是一个与文本本身操作有关的程序(创建、删除、信息取得—)

如果要想使用File类操作文件的话,那么肯定要通过构造方法实例化File类对象,而实例化File类对象的过程之中主要使用以下两种构造方法:

  1. 方法一:public File(String pathname);
  2. 方法二:public File(File parent,String child).

文件的基本操作,主要有以下几种功能:

  • **创建一个新文件:**public boolean createNewFile() throws IOException
  • **删除文件:**public Boolean delete();
  • **判断路径是否存在:**public Boolean exists();

创建新文件

package com.day14.demo;

import java.io.File;
import java.io.IOException;

public class FileDemo {
	public static void main(String[] args) throws IOException {
		File file = new File("f:\\hello.txt");
		file.createNewFile();
	}
}

如果文件存在进行删除,不存在进行创建

package com.day14.demo;

import java.io.File;
import java.io.IOException;

public class FileDemo {
	public static void main(String[] args) throws IOException {
		File file = new File("f:\\hello.txt");
		if(file.exists()){//文件存在
			file.delete();
		}else{//文件不存在
			file.createNewFile();//创建文件
		}
	}
}

本程序操作就表示如果文件存在则删除,如果不存在则创建一个新的文件,此时基本功能是实现了,不过这个程序此时存在三个问题:

问题一:关于路径的分隔符

在windows操作之中,使用“\”作为路径分隔符,而在Linux系统下使用“/”作为路径分隔符,而实际的开发而言,大部分情况下会在windows中做开发,而后将项目部署在Linus,那么此时,路径的分隔符都需要进行修改,这样实在是国语麻烦,为此在File类之中提供了一个常量:public static final String separator(按照Java的命名规范来讲,对于全局常量应该使用大写字母的方式定义,而此处使用的是小写,是由Java的发展历史所带来的问题)。

//由不同的操作系统的JVM来决定最终的separator是什么内容File file = new File("f:" + File.separator + "hello.txt");

问题二:是有可能会出现的延迟问题

发现程序执行完成之后,对于文件的创建或者是删除是会存在一些操作上的延迟,如果现在假设先删除了一个文件,而后立刻判断此文件是否存在,那么可能得到的结果就是错误的(为true),一位所有的*.class文件都要通过JVM与操作系统间接操作,这样就有可能会出现延迟的问题。

问题三:目录问题

之前进行文件创建的时候都是在根目录下创建完成的,如果说现在要创建的文件有目录呢?例如,现在要创建一个f:\hello\hello.txt文件,而此时在执行程序的时候hello目录不存在,这个时候执行的话就会出现错误提示:

Exception in thread "main" java.io.IOException: 系统找不到指定的路径。

因为现在目录不存在,所以不能创建,那么这个时候必须首先判断要创建文件的父路径是否存在,如果不存在应该创建一个目录,之后再进行文件的创建,而要想完成这样的操作,需要一下几个方法支持:

**找到一个指定文件的父路径:**public File getParentFile();

**创建目录:**public boolean mldirs()。

package com.day14.demo;

import java.io.File;
import java.io.IOException;

public class FileDemo {
	public static void main(String[] args) throws IOException {
		//由不同的操作系统的JVM来决定最终的separator是什么内容
		File file = new File("f:" + File.separator +"hello" + File.separator + "hello.txt");
		if(!file.getParentFile().exists()){//父目录
			file.getParentFile().mkdirs();//创建父目录
		}
		if(file.exists()){//文件存在
			file.delete();
		}else{//文件不存在
			file.createNewFile();//创建文件
		}
	}
}

以后在任何的java.io.File类开发过程之中,都一定要考虑文件目录的问题。

5.2 取得文件信息

在File类之中还可以通过以下的方法取得一些文件的基本信息:

方法名称 描述
public String getName() 取得文件的名称
public boolean isDirectory() 给定的路径是否为文件夹
public boolean isFile() 给定的路径是否是文件
public boolean isHidden() 是否是隐藏文件
public long lastModified() 文件的最后一次修改日期
public long length() 取得文件大小,是以字节为单位返回的。

获取文件的大小信息以及核心信息

package com.day14.demo;import java.io.File;import java.math.BigDecimal;import java.text.SimpleDateFormat;import java.util.Date;class MyMath{	public static double round(double num, int scale){		return Math.round(num * Math.pow(10, scale)) / Math.pow(10, scale);	}}public class FileDemo2 {	public static void main(String[] args) {		File file = new File("f:" + File.separator + "701_03_支付宝沙箱使用.avi");		if(file.exists() && file.isFile()){			System.out.println("1文件大小为:" + MyMath.round(file.length() / (double) 1024 / 1024, 2));			System.out.println("最后一次修改日期:"+ new SimpleDateFormat("YYYY-MM-dd HH:mm:ss").format(new Date(file.lastModified())));			System.out.println("2文件大小为:" + new BigDecimal(file.length() / (double)1024 /1024).divide(new BigDecimal(1), 2, BigDecimal.ROUND_HALF_UP).doubleValue());		}			}}

**列出目录内容:**public File [] listFiles(),此方法将目录中的所有文件以File对象数组的方式返回;

列出目录的所有结构

package com.day14.demo;

import java.io.File;
import java.util.Arrays;

public class FileDemo3 {
	public static void main(String[] args) {
		File file = new File("f:" + File.separator);
		if(file.exists() && file.isDirectory()){
			File[] listFiles = file.listFiles();
			System.out.println(Arrays.toString(listFiles));
		}
	}
}

5.3 综合案例:目录列表

现在希望把一个目录下的全部文件都列出来,那么这种情况下只能采用递归:因为列出一个目录下的全部文件或着文件夹之后,如果发现列出的内容是文件夹,则应该向后继续列出。

列出指定目录下的所有文件

package com.day14.demo;

import java.io.File;

public class FileListDemo {
	public static void main(String[] args) {
		File file = new File("f:" + File.separator);
		list(file);
	}
	public static void list(File file){
		if(file.isDirectory()){
			File[] files = file.listFiles();
			if(files != null){
				for (int i = 0; i < files.length; i++) {
				list(files[i]);//继续列出
				}
			}
		}
		System.out.println(file);
	}
}

线程阻塞问题

现在代码都在main线程下执行,如果该程序执行完成后才能继续执行下一条语句,要想解决这种耗时的问题。最好产生一个新的线程进行列出。

package com.day14.demo;import java.io.File;public class FileListDemo {	public static void main(String[] args) {		new Thread(()->{			File file = new File("f:" + File.separator);		list(file);		},"列出线程").start();				System.out.println("开始进行文件信息列出。。。。");	}	public static void list(File file){		if(file.isDirectory()){			File[] files = file.listFiles();			if(files != null){				for (int i = 0; i < files.length; i++) {				list(files[i]);//继续列出				}			}			}		System.out.println(file);	}}

6、IO— 字节流与字符流

字符流和字节流最本质的区别就是只有一个字节流是原生的操作,二字符流是经过处理后的操作。经过磁盘数据保存所保存的支持的数据类型只有:字节,所有磁盘中的数据必须先读到内存后才可以操作,内存里面会帮助我们把字节变为字符。字符更加适合处理中文。

**字节操作流:**OutputStream,InputStream;

**字符操作流:**Writer,Reader。

但是不管是字节流还是字符流的操作,本身都表示资源操作,而执行所有的资源都会按照如下几个步骤进行,下面以文件操作为例(对文件进行读,写操作):

  1. 要根据文件创建File对象
  2. 根据字节流或字符流的子类实例化我们的父类对象
  3. 进行数据的读取、写入操作
  4. 关闭流(clone())

对于IO操作属于资源处理,所有的对于资源的处理进行处理完成后必须进行关闭,否则资源就再也无法执行。

6.1 字节输出流:OutputStream

Java.io.OutputStream主要的功能是进行字节数据的输出的,而这个类的定义如下:

public abstract class OutputStream extends Object implements Closeable, Flushable

发现OutputStream类定义的时候实现了两个接口:Closeable,Flushable,这两个接口定义如下:

Closeable: Flushable:
public interface Closeable
extends AutoCloseable{
public void close() throws IOException;
}
public interface Closeable{
public void flush() throws IOException;
}

当取得了OutputStream类实例化对象之后,下面肯定要进行输出操作,在OutputStream类之中定义了三个方法:

**输出单个字节数组数据:**public abstract void write(int b) throws IOException

**输出一组字节数组数据:**public void write(byte[] b) throws IOException

**输出部分字节数组数据:**public void write(byte[] b,int off,int len) throws IOException

提示:对于Closeable继承的AutoCloseable接口

AuotCloseable实在JDK1.7的时候又增加了一个新的接口,但是这个接口的定义和Closeable定义是完全一样的,我个人认为:有可能在一些其他的类上出现了自动的关闭功能,Closeable是手工关闭,AutoCloseable属于自动关闭。

但是对于Closeable和Flushable这两个接口实话而言不需要关注,因为从最早的习惯对于flush()和close()连个方法都是直接在OutputStream类之中定义的,所以很少去关心这些父接口问题。

对于OutputStream类而言发现其本身定义的是一个抽象类(abstract class),按照抽象类的使用原则来讲,如果要想为父类实例化,那么就需要使用子类,就需要定义抽象的子类,而现在如果要执行的是文件操作,则可以使用FileOutputStream子类完成。如果按照面向对象的开发原则,子类要为抽象类进行对象的实例化,而后调用的方法以父类中定义的方法为主,而具体的实现找实例化这个父类的子类完成,也就是说在整个的操作之中,用户最关心的只有子类的构造方法:

**实例化FileOutputStream(新建数据):**public FileOutputStream([File file) throws FileNotFoundException

**实例化FileOutputStream(追加数据):**public FileOutputStream(File file,boolean append) throws FileNotFoundException

实现文件内容的输出

package com.day14.demo;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class OutputDemo {
	public static void main(String[] args) throws Exception {
		//1.定义文件路径
		File file = new File("f:" + File.separator + "test" + File.separator + "hello.txt");
		if(!file.getParentFile().exists()){//父路径不存在
			file.getParentFile().mkdirs();//创建父目录
		}
		//2.要输出的数据
		String str = "Hello,zsr!!!!";
		//3.实例化对象
		FileOutputStream stream = new FileOutputStream(file);
		//4.将内容写进stream
		stream.write(str.getBytes());//输出数据,要将输出的数据变为字节数组输出
		//5.关闭流
		stream.close();
	}
}

这里默认执行时进行文档内容的覆写,如果不希望进行文档内容的覆写可以直接将FileOutputStream改为

FileOutputStream stream = new FileOutputStream(file,true);

如果对写入的内容需要换行操作必须使用\r\n进行换行操作。

6.2 字节输入流:InputStream

如果现在要从指定的数据源之中读取数据,使用InputStream,而这个类的定义如下:

public abstract class InputStreamextends Objectimplements Closeable

发现InputStream只实现了Closeable接口

在InputStream之中定义了三个读取数据的方法:

**读取单个字节:**public abstract int read() throws IOException

**说明:**每次执行read()方法都会读取一个数据源的指定数据,如果现在发现已经读取到了结尾则返回-1.

**读取多个字节:**public int read(byte[] b) throws IOException

**说明:**如果现在要读取的数据小于开辟的字节数组,这个时候read()方法的返回值int返回的是数据个数;如果现在开辟的字节数组小于读取的长度,则这个时候返回就是长度;如果数据已经读完了,则这个时候的int返回的是-1.

**读取指定多个字节:**public int read(byte[] b,int off,int len) throws IOException

**说明:**每次只读取传递数组的部分内容,如果读取满了,返回就是长度;如果没有读取满,返回的就是读取的个数;如果读取到最后没有数据了,就返回-1

既然InputStream为抽象类,那么这个抽象类要使用就必须有子类,现在是通过文件读取内容,肯定使用FileInputStream子类进行操作,与OutputStream类的使用一样,对于FileInputStream也只关心构造方法:

**FileInputStream****类构造方法:public FileInputStream(File file) throws FileNotFoundException

文件信息的读取

package com.day14.demo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class InputDemo {
	public static void main(String[] args) throws Exception {
		File file = new File("f:" + File.separator + "test" + File.separator + "hello.txt");
		if(!file.exists()){
			System.out.println("指定文件不存在!!");
		}else{
			FileInputStream is = new FileInputStream(file);
			byte[] result = new byte[1024];
			int length = is.read(result);
			System.out.println("读取的内容为:" + new String(result,0,length));
		}
	}
}

6.3 字符输出流:Writer

Writer类也是一个专门用来数据输出的操作类,对于中文数据来说是比较友好的,这个类定义:

public abstract class Writer
extends Object
implements Appendable, Closeable, Flushable

在Writer类之中定义的writer()方法都是以字符数据为主,但是在这些方法之中,只关心一个:

**输出一个字符串:**public void write(String str) throws IOException

如果要操作文件肯定使用FileWriter子类。

package com.day14.demo;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class WriterDemo {
	public static void main(String[] args) throws IOException {
		//1.定义文件路径
		File file = new File("f:" + File.separator + "test" + File.separator + "hello.txt");
		if(!file.getParentFile().exists()){//父路径不存在
			file.getParentFile().mkdirs();//创建父目录
		}
		//2.要输出的数据
		String str = "我正在学java这门课程!!!!\r\n";
		//如果想要进行内容不覆盖的直接使用true就可以了
		//FileWriter out = new FileWriter(file,true);
		FileWriter out = new FileWriter(file);
		out.write(str);
		out.close();
	}
}

6.4 字符输入流:Reader

Reader是进行字符数据读取的一个操作类,其定义:

public abstract class Reader
extends Object
implements Readable, Closeable

在Writer类之中存在了直接输出一个字符串数据的方法,可是在Reader类之中并没有定义这样的方法,只是定义了三个按照字符串读取的方法?为什么会这样?

因为在使用OutputStream输出数据的时候,其程序可以输出的大小一定是程序可以承受的数据的大小,那么如果说使用InputStream读取的时候,可能被读取的数据非常大,那么如果一次性全读进来,就会出现问题,所以只能一个一个的进行读取。

Reader依然是抽象类,那么如果从文件读取,依然使用FileReader类

package com.day14.demo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class ReadDemo {
	public static void main(String[] args) throws IOException {
		File file = new File("f:" + File.separator + "test" + File.separator + "hello.txt");
		if(!file.exists()){
			System.out.println("指定文件不存在!!");
		}else{
			FileReader reader = new FileReader(file);
			char[] result = new char[1024];
			int length = reader.read(result);
			System.out.println("读取的内容为:" + new String(result,0,length));
		}
	}
}

字符比字节的好处就是在于字符串数据的支持上,而这个好处还只是在Writer()类中体现,所以与字节流相比,字符流的操作并不是对等的关系。

6.5 字节流与字符流区别

通过我们一系统的分析,可以发现字节流和字符流的代码操作区别不大,如果从我们实际的使用,我们字节流是优先考虑,只有再我们使用中文的时候才考虑使用字符流,因为所有的字符都需要通过内存缓冲来进行处理。

既然读数据需要缓存的处理,那么写数据也同样需要。如果使用字符流没有进行刷新,那么我们的内容可能再缓存之中,所以必须进行强制刷新才能得到完整的数据内容。

package com.day14.demo;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class WriterDemo {
	public static void main(String[] args) throws IOException {
		//1.定义文件路径
		File file = new File("f:" + File.separator + "test" + File.separator + "hello.txt");
		if(!file.getParentFile().exists()){//父路径不存在
			file.getParentFile().mkdirs();//创建父目录
		}
		//2.要输出的数据
		String str = "我正在学java这门课程!!!!\r\n";
		//如果想要进行内容不覆盖的直接使用true就可以了
		//FileWriter out = new FileWriter(file,true);
		FileWriter out = new FileWriter(file);
		out.write(str);
		out.flush();
	}
}

在以后的IO处理的时候,如果处理的是图片、音乐、文字都可以使用字节流,只有再处理中文的时候才会使用字符流。

7、转换流

现在对于IO操作就存在了字节流和字符流两种操作,那么对于这两种操作流之间也是可以进行转换的,而转换的操作类有两个:

将字节输出流变为字符输出流(OutputStream->Writer)——OutputStreamWriter;

将字节输入流变为字符输入流(InputStream->Reader)——InputStreaReader。

OutputStreamWriter InputStreamReader
public class OutputStreamWriter extends Writer public class InputStreamReader extends Reader
public OutputStreamWriter(OutputStream out) public InputStreamReader(InputStream in)

通过以上的继承结构和构造方法可以清楚发现,既然OutputStreamWriter是Writer的子类,那么必然OutputStreamWriter可以通过Writer类执行对象的向上转型进行接收,而同时这个OutputStreamWriter类的构造方法可以接收OutputStream,这样就可以完成转型。

将字节输出流变为字符输出流

package com.day14.demo;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;

public class OutWriterDemo {
	public static void main(String[] args) throws Exception {
		//1.定义文件路径
		File file = new File("f:" + File.separator + "test" + File.separator + "hello.txt");
		if(!file.getParentFile().exists()){//父路径不存在
			file.getParentFile().mkdirs();//创建父目录
		}
		//2.要输出的数据
		String str = "Hello,world!!!!";
		//3.实例化对象
		OutputStream stream = new FileOutputStream(file,true);
		//4.将内容写进stream
		Writer out = new OutputStreamWriter(stream);
		out.write(str);
		//5.关闭流
		out.close();
	}
}

对于文件操作可以使用FileInputStream,FileOutputStream,FileReader,FileWriter四个类,那么下面分别观察这四个类的继承结构。

观察FileInputStream,FileOutoutStream类的继承结构

FileInputStream FileOutoutStream
java.lang.Object
java.io.InputStream
java.io.FilterInputStream
java.lang.Object
java.io.OutputStream
java.io.FileOutputStream

观察FileReader,FileWriter类的继承结构

FileReader FileWrite
java.lang.Object
java.io.Reader
java.io.InputStreamReader
java.io.FileReader
java.lang.Object
java.io.Writer
java.io.OutputStreamWriter
java.io.FileWriter

通过以上的继承关系也可以发现,实际上所有的字符数据都是需要进行转换的,依靠转换流完成,以后真正保存或者是传输的数据是不可能有字符的,全部都是字节,而字节只是在电脑之中处理后的结果。

到此这篇关于Day14基础不牢地动山摇-Java基础的文章就介绍到这了,更多相关Java基础内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 一篇文章带你深入了解Java基础(3)

    目录 1.方法的基本定义 2.方法重载 3.方法的递归调用 4.面向对象的前身是面向过程 5.类与对象 总结 1.方法的基本定义 限制条件:本次所讲解的方法指的是在主类中定义,并且由主方法由主方法直接调用. 方法是指就是一段可以被重复调用的代码块. 在java里面如果想要进行方法的定义,则可以使用如下的方法进行完成. public static 方法返回值 方法名称([参数类型 变量,....]){ 方法体代码 ; return [返回值]; } 在定义方法的时候对于方法的返回值由以下两类:vo

  • 一篇文章带你深入了解Java基础

    目录 1.String类 1.1两种对象实例化方式 1.2字符串比较 1.3字符串常量是String的匿名对象 1.4String两种实例化方式区别 1.分析直接赋值方式 2.构造方法赋值 1.5字符串常量不可改变 1.6开发中String必用 1.7字符串和字符数组 1.9字符串比较 1.11字符串的替换 1.12字符串的拆分 1.12字符串的截取 1.13其他操作方法 2.1. 给定一个email地址,要求验证其是否正确,提示:可以简单的验证一下,重点验证"@"和".&q

  • 一篇文章带你深入了解Java基础(2)

    目录 1.Java主要特点 2.计算机的高级汇编语言类型: 3.JVM(Java Visual Machine) 4.编写第一个Java程序并运行 5.CLASSPATH指的是类加载路径 6.程序注释,对以后的所有代码都要进行注释,主页可以方便进行开发需求 7.标识符和关键字 8.Java数据类型的划分以及数据类型的操作 9.运算符 自增.自减操作 总结 1.Java主要特点 简单性.跨平台性.分布性.安全性.健壮性.平台独立与可移植性.多线程.动态性.面向对象的编程语言.支持垃圾自动收集处理等

  • 一篇文章带你深入了解Java基础(4)

    目录 1.private实现封装处理 2.构造方法与匿名对象 3.简单java类 4.数组 总结 1.private实现封装处理 如果像想要知道封装,首先必须清楚如果没有封装会怎么样? 没有封装方法中的属性,在所有方法被调用后都可以进行无权限的访问.而当进行了封装操作之后,在实例化对象访问该方法的时候会出现无法访问的问题. TestDemo1.java:11: 错误: name 在 Person 中是 private 访问控制 per.name = "张三"; ^ TestDemo1.

  • 一篇文章带你深入了解javaIO基础

    目录 一.认识IO 1.IO的分类 2.IO的方式 3.IO读写的方式 4.IO的特性 二.文件操作 1.文件的构成 2.文件的创建 3.文件操作的API使用 三.IO流 1.流的分类 2.流的创建 3.流的使用 <1>输入流 <2>输出流 <3>实例:文件的复制 总结 一.认识IO 1.IO的分类 (1)BIO:同步阻塞IO (2)NIO:同步非阻塞IO (3)AIO:异步阻塞IO 注意: 这里主要介绍BIO 2.IO的方式 IO本质就是对数据的操作 (1)网络IO

  • Day14基础不牢地动山摇-Java基础

    目录 1.定时器 2.UUID类 3.Base64加密处理 加密处理 多次加密 4.ThreadLocal类 5.IO-File类 5.1 基本操作 5.2 取得文件信息 5.3 综合案例:目录列表 6.IO- 字节流与字符流 6.1 字节输出流:OutputStream 6.2 字节输入流:InputStream 6.3 字符输出流:Writer 6.4 字符输入流:Reader 6.5 字节流与字符流区别 7.转换流 1.定时器 推动整个计算机硬件的发展的核心关键性技术就是时钟.所以在企业开

  • Day10基础不牢地动山摇-Java基础

    目录 1.异常的捕获与处理 1.1 处理异常 1.2 异常处理的流程 1.3 throw关键字 1.4 异常处理模型 1.5 RuntimeException 1.6 断言:assert 1.7 自定义异常 2.链表 2.1 链表基本的结构 2.2 链表实现结构说明 2.3 增加链表数据-public void add(数据) 2.4 增加多个数据-public void addAll(数据数组) 2.5 统计数据个数-public int size() 2.6 链表数据转换为对象数组-publ

  • Day15基础不牢地动山摇-Java基础

    目录 1.字符编码 1.1 常用字符编码 1.2 乱码产生分析 2.内存流基本操作 3.打印流 3.1 格式化文本信息 4. System类 4.1 系统输出 4.2 系统输出 4.3 系统输入 5.BufferedReader类 6.Scanner 7.对象序列化 7.1 对象序列化的概念 7.2 实现序列化和反序列化 7.3 transient关键字(了解) 1.字符编码 1.1 常用字符编码 在计算机的世界之中,所有的显示文字都是按照其指定的数字编码进行保存的,如果没有正确的解码,那么就坑

  • Day16基础不牢地动山摇-Java基础

    目录 1.反射机制 1.1 认识反射 1.2 取得父类信息 1.3 反射调用构造 1.4 反射调用方法 1.5 反射调用成员 1.6 反射与简单Java类-单级VO操作原理 1.7 单极自动VO设置实现 1.8 反射与简单Java类-多级VO设置实现 2.ClassLoader类加载器 2.1 认识类加载器 2.2 自定义ClassLoader 1.反射机制 反射机制如果只是针对普通开发者而言意义不大,一般都是作为一些系统的构架设计去使用的,包括以后学习的开源框架,那么几乎都是反射机制. 1.1

  • Day11基础不牢地动山摇-Java基础

    目录 1.Eclipse开发工具 1.1 Eclipse历史 1.2 快捷键 1.3 Debug调试 1.4 JUNIT测试工具 2.Java基础新特性 2.1 可变参数 2.2 foreach输出 2.3 静态导入 3. JDK三大主要特性--泛型 3.1 泛型的引出 3.2 泛型实现 3.3 通配符 3.4 泛型接口 3.5 泛型方法 4.JDK三大主要特性--枚举 4.1 多例与枚举 4.2 Enum类 面试题:请解释enum和Enum的区别? 4.3 枚举中定义其它结构 4.4 枚举应用

  • Day12基础不牢地动山摇-Java基础

    目录 1.多线程 1.1 多线程的基本概念 1.2 多线程的实现 1.3 继承Thread类实现多线程 1.4 Runnable接口实现多线程 1.5 Thread类和Runnable接口实现多线程的区别 1.6 线程的操作状态 1.7 Callable实现多线程 1.8 线程命名和取得 1.9 线程的休眠 1.10 线程的优先级 1.11 线程的同步与死锁 1.12 死锁 综合案例 1.解决数据错位问题:依靠同步解决 2.解决数据的重复设置和重复取出 面试题:请解释sleep()和wait()

  • 基础不牢,地动山摇,Java基础速来刷刷

    Java类结构以及main函数 类是Java中最基础的逻辑单位 java所有内容都是需要在类中的,内容不允许游离在类之外,简单说Java项目就是由一个个类组成 类的构成 成员变量/属性 成员方法/函数 注意:Java要求文件名和类名需要一致 main函数 这里的main函数特指psvm,主方法 一个class文件最多只能有一个main函数 一个类可以没有main函数,没有main函数的类就不能主动执行,但是可以被动(被调用执行) main函数是程序的入口,和C/C++一致,但是Java要求所有的

  • Java基础之匿名内部类、包装类

    目录 1.匿名内部类 2.Object类简介 2.1 取得对象信息toString() 2.2 对象的比较equals() 2.3 Object接口引用数据类型 3.包装类 3.1 装箱与拆箱 3.2 字符串与基本数据类型的转换 3.3 包的定义 3.4 包的导入 4.访问控制权限 5.jar命令 1.匿名内部类 内部类:在一个类的内部定义了另外的类,称为内部类,匿名内部类指的是没有名字的内部类.为了清楚内部类的主要作用,下面首先观察一个代码. interface IMessage{ publi

  • Java基础字符编码与内存流详细解读

    目录 1.字符编码 1.1 常用字符编码 1.2 乱码产生分析 2.内存流基本操作 3.打印流 3.1 格式化文本信息 4. System类 4.1 系统输出 4.2 系统输出 4.3 系统输入 5.BufferedReader类 6.Scanner 7.对象序列化 7.1 对象序列化的概念 7.2 实现序列化和反序列化 7.3 transient关键字(了解) 1.字符编码 1.1 常用字符编码 在计算机的世界之中,所有的显示文字都是按照其指定的数字编码进行保存的,如果没有正确的解码,那么就坑

  • Java基础知识汇总

    Java基础知识 1.Java语言的优点: 1)Java是纯面向对象语言 2)与平台无关性,一次编译到处运行 3)Java提供了狠多内置类库 4)提供了对web应用的支持 5)具有较好的安全性(数组边界检测.Bytecode检测)和健壮性(强制型机制.垃圾回收器.异常处理) 6)去除c++难以理解的一些特性(头文件 指针 运算符重载 多重继承) 2.java与c++的异同: 1)Java为解释型语言,c++为编译型语言,java会慢但是跨平台 2)Jave为纯面向对象,c++既面向对象又能面向过

随机推荐