Java基础20(文件操作 IO流 InputStream字节输入流 OutputStream字节输出流 Writer 字符输出流)

目录

一、File 文件对象

1. 创建对象

2. 相对路径和绝对路径

3. 一些方法

汇总:

获取文件信息1:

判断文件:

删除文件:

创建文件:

获取文件信息2:

4. 小结

二、IO流

1. InputStream字节输入流

1.1 构造方法

1.2 读取

1.3 BufferedInputStream

1.4 小结

2. OutputStream字节输出流

2.1 构造方法

2.2 写入

2.3 BufferedOutputStream

2.4 实现文件的复制

2.5 小结

3. Writer字符输出流

3.1 构造方法

3.2 一些方法

3.3 BufferedWriter 

4. Reader 字符输入流


一、File 文件对象

在计算机系统中,文件是非常重要的存储方式。Java的标准库java.io提供了File对象来操作文件和目录。要构造一个File对象,需要通过构造方法,传入该文件的本地物理路径。

创建文件和文件夹:

// 创建一个存在的文件夹
		File f1 = new File("D:\\课件整理和发送\\javaSE2404班\\Test");
		// 创建一个存在的文件
		File f2 = new File("D:\\课件整理和发送\\javaSE2404班\\Test\\a.txt");
		// 创建一个不存在的文件夹
		File f3 = new File("D:\\课件整理和发送\\javaSE2404班\\Test\\aaa");
		// 创建一个不存在的文件
		File f4 = new File("D:\\课件整理和发送\\javaSE2404班\\Test\\b.txt");

1. 创建对象

构造方法1:

public File(String pathname):以pathname为路径创建File对象,可以是绝对路径或者相对路径

构造方法2:

public File(String parent,String child)以parent为父路径,child为子路径创建File对象

构造方法3:

public File(File parent,String child)根据一个父File对象和子文件路径创建File对象

示例:

// 构造方法2
		// public File(String parent,String child)
		// 以parent为父路径,child为子路径创建File对象
		String parent = "D:\\课件整理和发送\\javaSE2404班\\Test";
		String child = "b.txt";
		File f1 = new File(parent, child);
		System.out.println(f1);

		// 构造方法3
		// public File(File parent,String child)
		// 根据一个父File对象和子文件路径创建File对象
		File parentF1 = new File(parent);
		File f2 = new File(parentF1, child);
		System.out.println(f2);

注意事项:
●一个File对象代表指向硬盘中的一个文件或者目录路径
●无论该路径下是否存在文件或者目录,都不影响File对象的创建

2. 相对路径和绝对路径

构造File对象时,既可以传入绝对路径,也可以传入相对路径。绝对路径是以根目录开头的完整路径。
注意:Windows平台使用\作为路径分隔符,在Java字符串中需要用\\表示一个\。

File f = new File("C:\\Windows\\notepad.exe");

Linux平台使用/作为路径分隔符:

File f = new File("/usr/bin/javac");

绝对路径:从盘符开始

传入相对路径时,相对路径前面加上当前目录就是绝对路径,可以用.表示当前目录,..表示上级目录。

// 假设当前目录是C:\Docs
File f1 = new File("sub\\javac"); // 绝对路径是C:\Docs\sub\javac
File f3 = new File(".\\sub\\javac"); // 绝对路径是C:\Docs\sub\javac
File f3 = new File("..\\sub\\javac"); // 绝对路径是C:\sub\javac

File对象有3种形式表示的路径,一种是getPath(),返回构造方法传入的路径,一种是getAbsolutePath(),返回绝对路径,一种是getCanonicalPath(),它和绝对路径类似,但是返回的是规范路径。

//public String getAbsolutePath():获取文件的绝对路径
//		 public String getPath() :获取路径,返回定义文件时使用的路径
//		 public String getCannoicalPath() 获取规范路径
		
		File f1=new File("D:\\课件整理和发送\\javaSE2404班\\Test\\a.txt");
	    System.out.println("文件的绝对路径:"+f1.getAbsolutePath());
	    System.out.println("获取路径            :"+f1.getPath());
	    System.out.println("获取规范路径    :"+ f1.getCanonicalPath());
        System.out.println("=============f2=================");
	    File f2 = new File("sub\\javac"); 
	    System.out.println("文件的绝对路径:"+f2.getAbsolutePath());
	    System.out.println("获取路径            :"+f2.getPath());
	    System.out.println("获取规范路径    :"+ f2.getCanonicalPath());

	    System.out.println("=============f3=================");
	    File f3 = new File(".\\sub\\javac"); 
	    System.out.println("文件的绝对路径:"+f3.getAbsolutePath());
	    System.out.println("获取路径            :"+f3.getPath());
	    System.out.println("获取规范路径    :"+ f3.getCanonicalPath());

	    
	    System.out.println("=============f4=================");
	    File f4 = new File("..\\sub\\javac");
	    System.out.println("文件的绝对路径:"+f4.getAbsolutePath());
	    System.out.println("获取路径            :"+f4.getPath());
	    System.out.println("获取规范路径    :"+ f4.getCanonicalPath());

运行结果:

3. 一些方法

汇总:

获取文件信息:
    

public String getName() :获取文件的名称,带后缀
public long length() :获取文件长度(即:字节数---真实的大小)。不能获取目录的长度--仅表示当前操作系统为保存目录所涉及的长度。
public long lastModified() :获取最后一次的修改时间,毫秒值 
使用new Date(f1.lastModified());// 返回的是当天时间
public String getAbsolutePath():获取文件的绝对路径
public String getPath() :获取路径,返回定义文件时使用的路径
public String getCannoicalPath() 获取规范路径
public String[] list() :获取指定目录下的所有文件或者文件目录的名称数组---注意返回类型
public File[] listFiles() :获取指定目录下的所有文件或者文件目录的File数组----返回时File
注意:
1.在使用时要确认其是一个目录(如果是文件返回为null,如果没有权限访问此目录返回也是null)

2.当文件对象代表一个空文件夹时 返回一个长度为0的数组

3.当文件对象是一个有内容的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回

4.单文件对象是一个有隐藏文件的文件夹时,将里面所有文件和文件夹的路径放入File数组中放回,包含隐藏文件

判断文件:
        

public boolean exists() :判断是否存在
public boolean isDirectory():判断是否是目录
public boolean isFile() :判断是否是文件
public boolean canRead() :判断是否可读
public boolean canWrite() :判断是否可写
public boolean isHidden() :判断是否隐藏

删除文件:

public boolean delete():删除此抽象路径名表示的文件或者文件夹

注意:delete方法只删除文件和空文件夹,是直接删除不走回收站

创建文件:

public boolean createNewFile()创建文件。若文件存在,则不创建,返回false
public boolean mkdir() :创建文件目录。如果此文件目录存在,就不创建了。如果此文件目录的上层目录不存在,也不创建。
public boolean mkdirs() :创建文件目录。如果上层文件目录不存在,一并创建

获取文件信息1:

●public String getName() :获取文件的名称,带后缀
●public long length() :获取文件长度(即:字节数---真实的大小)
。不能获取目录的长度--仅表示当前操作系统为保存目录所涉及的长度。
●public long lastModified() :获取最后一次的修改时间,毫秒值

// 创建一个存在的文件夹
		File f1 = new File("D:\\课件整理和发送\\javaSE2404班\\Test");
		// 创建一个存在的文件
		File f2 = new File("D:\\课件整理和发送\\javaSE2404班\\Test\\a.txt");
		// 创建一个不存在的文件夹
		File f3 = new File("D:\\课件整理和发送\\javaSE2404班\\Test\\aaa");
		// 创建一个不存在的文件
		File f4 = new File("D:\\课件整理和发送\\javaSE2404班\\Test\\b.txt");
		
		
		// public String getName() :获取文件的名称,带后缀
		// public long length() :获取文件长度(即:字节数---真实的大小)。不能获取目录的长度--仅表示当前操作系统为保存目录所涉及的长度。
		// public long lastModified() :获取最后一次的修改时间,毫秒值

		System.out.printf("[%s]目录的长度[%d],最后一次修改时间[%s]\n",f1.getName(),f1.length(),new Date(f1.lastModified()));
		System.out.printf("[%s]文件的长度[%d],最后一次修改时间[%s]\n",f2.getName(),f2.length(),new Date(f2.lastModified()));
		System.out.printf("[%s]目录的长度[%d],最后一次修改时间[%s]\n",f3.getName(),f3.length(),new Date(f3.lastModified()));
		System.out.printf("[%s]文件的长度[%d],最后一次修改时间[%s]\n",f4.getName(),f4.length(),new Date(f4.lastModified()));

●public String getAbsolutePath():获取文件的绝对路径
●public String getPath() :获取路径,返回定义文件时使用的路径
●public String getCannoicalPath():获取规范路径


判断文件:

●public boolean exists() :判断是否存在
●public boolean isDirectory():判断是否是目录
●public boolean isFile() :判断是否是文件

// 创建一个存在的文件夹
		File f1 = new File("D:\\课件整理和发送\\javaSE2404班\\Test");
		// 创建一个存在的文件
		File f2 = new File("D:\\课件整理和发送\\javaSE2404班\\Test\\a.txt");
		// 创建一个不存在的文件夹
		File f3 = new File("D:\\课件整理和发送\\javaSE2404班\\Test\\aaa");
		// 创建一个不存在的文件
		File f4 = new File("D:\\课件整理和发送\\javaSE2404班\\Test\\b.txt");

//	     public boolean exists() :判断是否存在
//	     public boolean isDirectory():判断是否是目录
//	     public boolean isFile() :判断是否是文件
		System.out.printf("目录%s是否存在%s,是否是目录%s,是否是文件%s\n", f1.getName(), f1.exists(), f1.isDirectory(), f1.isFile());
		System.out.printf("文件%s是否存在%s,是否是目录%s,是否是文件%s\n", f2.getName(), f2.exists(), f2.isDirectory(), f2.isFile());
		System.out.printf("目录%s是否存在%s,是否是目录%s,是否是文件%s\n", f3.getName(), f3.exists(), f3.isDirectory(), f3.isFile());
		System.out.printf("文件%s是否存在%s,是否是目录%s,是否是文件%s\n", f4.getName(), f4.exists(), f4.isDirectory(), f4.isFile());

删除文件:

●public boolean delete();

注意:delete方法只删除文件和空文件夹,是直接删除不走回收站

// public boolean delete():
		// 注意:delete方法只删除文件和空文件夹,是直接删除不走回收站
		// 文件
		File f1 = new File("D:\\课件整理和发送\\javaSE2404班\\Test\\a.txt");
		// 有内容的文件夹
		File f2 = new File("D:\\课件整理和发送\\javaSE2404班\\Test");
		// 没有内容的文件夹
		File f3 = new File("D:\\课件整理和发送\\javaSE2404班\\Test\\b");

		boolean b1 = f1.delete();
		System.out.println("删除磁盘上的文件是否成功"+b1);
		boolean b2 = f2.delete();
		System.out.println("删除磁盘上的目录是否成功"+b2);
		boolean b3 = f3.delete();
		System.out.println("删除磁盘上的目录是否成功"+b3);

创建文件:

●public boolean createNewFile():路径要存在,创建文件。若文件存在,则不创建,返回false,如果不存在,则创建,返回true

●public boolean mkdir() : 创建文件目录。如果此文件目录存在,就不创建了。如果此文件目录的上层目录不存在,也不创建。

●public boolean mkdirs() :创建文件目录。如果上层文件目录不存在,一并创建

File f1 = new File("D:\\课件整理和发送\\javaSE2404班\\Test\\a.txt");
		// b的目录不存在,但是根目录存在
		File f2 = new File("D:\\课件整理和发送\\javaSE2404班\\Test\\b");
		File f3 = new File("D:\\课件整理和发送\\javaSE2405班\\Test\\a\\b");

		//public boolean createNewFile()//路径要存在,
		//创建文件。若文件存在,则不创建,返回false,如果不存在,则创建,返回true
		boolean b1=f1.createNewFile();
		System.out.println(b1);
		
//		public boolean mkdir() :
//		创建文件目录。如果此文件目录存在,就不创建了。
//		如果此文件目录的上层目录不存在,也不创建。
		boolean b2 =f2.mkdir();
		System.out.println("文件夹创建是否成功:"+b2);
		
//		public boolean mkdirs() :
//		创建文件目录。如果上层文件目录不存在,一并创建
		boolean b3 =f3.mkdirs();
		System.out.println("文件夹创建是否成功:"+b3);

获取文件信息2:

路径空间:

●public string[] list(): 获取指定目录下的所有文件或者文件目录的名称数组---注意返回类型

	File f1 = new File("D:\\java2404code\\Test");
//		public string[] list():
//			获取指定目录下的所有文件或者文件目录的名称数组---注意返回类型
			String[] resultstrings= f1.list();
			for(String string :resultstrings){
			System.out.println(string);
			} 

●public File[] listFiles():获取指定目录下的所有文件或者目录的File数组----返回时File

	File f1 = new File("D:\\java2404code\\Test");

//		public File[] listFiles():
//		获取指定目录下的所有文件或者目录的File数组----返回时File
		File[] files = f1.listFiles();
		for (File file : files) {
			String type = file.isFile() ? "文件" : "目录";
			long length = file.length();
			String name = file.getName();
			Date date = new Date(file.lastModified());
			System.out.printf("%s[%s]的大小为%d,最后一次的修改时间为%s\n", type, name, length, date);
		}
	}

●递归获取所有目录和子目录及文件:

File f1 = new File("D:\\java2404code\\Test");
		//递归方式遍历多层目录
		showFileTree(f1);

	}

	//输出文件夹下的所有文件和目录
	public static void showFileTree(File dir) {
		File[] files = dir.listFiles();
		for (File file : files) {
			String name = file.getName();
			Date date = new Date(file.lastModified());
			//判断是否是目录
			if (file.isDirectory()) {
				System.out.printf("目录[%s],最后一次的修改时间为%s\n", name, date);
				//如果当前的file对象是一个目录,继续调用ShowFileTree
				//显示该文件对象的子目录和子文件
				showFileTree(file);
			} else {
				long length = file.length();
				System.out.printf("文件[%s]的大小为%d,最后一次的修改时间为%s\n", name, length, date);

			}
		}
	}

递归方式求1-n:

	// 递归方式求1-n
		System.out.println(sum(4));// 10
	}

	public static int sum(int n) {
		if (n == 1) {
			return 1;
		}
		return n + sum(n - 1);
	}

File f1 = new File("D:\\java2404code\\Test");
		//使用FileFilter进行过滤文件
		File[] files = f1.listFiles(new FileFilter() {
			
			@Override
			public boolean accept(File pathname) {
				if (pathname.getName().endsWith(".txt")) {
					return true;//保留
				}
				return false;//为false则过滤此文件,不保存
			}
		});
		
		//遍历文件
		for (File file : files) {
			System.out.println(file.getName());
		}

4. 小结

Java标准库的java.io.File对象表示一个文件或者目录:
●创建File对象本身不涉及IO操作;
●可以获取路径/绝对路径/规范路径:getPath()/getAbsolutePath()/getCanonicalPath();
●可以获取目录的文件和子目录:list()/listFiles();
●可以创建或删除文件和目录。

二、IO流

I 表示Input ,把硬件文件的数据读入到内存的过程,称之输入,负责读

O表示output ,把内存中的数据写出到硬盘文件的过程 称之输出 负责写

总览:

IO:
字节   字符    输入  输出

字节输入:InputStream 抽象类
                   常用的方法:
                  int read()
                  int read(byte[] b)
                  void  close()
                   实现类:
            FileInputStrem
                  构造方法: (File f1)
                         (String pathName)
            BufferedInputStream
                 构造方法:(InputStrem is)
                 
字节输出: OutputStream 抽象父类
                     常用方法:
                 write(byte[] b);
                 write(int data);
                 write(byte[] b,int offer,int lenth);
                     实现类:
               FileOutputStream
                      构造方法: (String pathName)
                                (File f1)
                                (String pathName,boolean append)
                                (File f1,boolean append)
               BufferedOutputStream
                       构造方法:(OutputStream is)
                       
 
字符输出流:Writer
                 常用方法:  write(int data)
                  write(char[] ch)
                  write(char[] ch,int index,int length)
                  write(String str)
                  write(String str,int index,int length)
        实现类:  FileWriter
                     构造方法: (String pathName)
                                (File f1)
                                (String pathName,boolean append)
                                (File f1,boolean append)
                BufferedWriter
                    构造方法: (Writer is)
                    newLines() 换行
                    
                    
                
字符输入流:Reader

URL url =new URL("url地址");
URLconnection   con =url.getConnection()
con.open()
getInputSteam()

1. InputStream字节输入流

InputStream就是Java标准库提供的最基本的输入流。它位于java.io这个包里。java.io包提供了所有同步IO的功能。要特别注意的一点是,InputStream并不是一个接口,而是一个抽象类,它是所有输入流的超类。

1.1 构造方法

路径情况:

构造方法1:

FileInputStream(String name);通过打开与实际文件的连接来创建一个 FileInputstream ,该文件由文件系统中的路径名 name命名。
//		构造方法1:
//		FileInputStream(String name)
//		通过打开与实际文件的连接来创建一个 FileInputstream ,该文件由文件系统中的路径名 name命名。
		String name = "D:\\java2404code\\Test\\a.txt";
		InputStream is =  new FileInputStream(name);
		System.out.println(is);//java.io.FileInputStream@15db9742

构造方法2:

FileInputStream(File file);   通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
//		构造方法2:
//		FileInputStream(File file);
//		通过打开与实际文件的连接来创建一个FileInputstream ,该文件由文件系统中的 File对象 file命名。
		File f1 =  new File(name);
		InputStream is1 = new FileInputStream(f1);
		System.out.println(is1);

1.2 读取

int read()

int read(byte[] b)

void  close()

●int read() 读取字节信息,一个一个字节内容读取,读取到末尾返回值为-1

●int read(byte b[]) 每次读取数组b长度个字节,存在byte字节数组b中,读到末尾返回-1

在读取流的时候,一次读取一个字节并不是最高效的方法。很多流支持一次性读取多个字节到缓冲区,对于文件和网络流来说,利用缓冲区一次性读取多个字节效率往往要高很多。InputStream提供了两个重载方法来支持读取多个字节:
●int read(byte[] b):读取若干字节并填充到byte[]数组,返回读取的字节数
●int read(byte[] b, int off, int len):指定byte[]数组的偏移量和最大填充数

利用上述方法一次读取多个字节时,需要先定义一个byte[]数组作为缓冲区,read()方法会尽可能多地读取字节到缓冲区, 但不会超过缓冲区的大小。read()方法的返回值不再是字节的int值,而是返回实际读取了多少个字节。如果返回-1,表示没有更多的数据了。

try {
			//字节输入流,读取磁盘文件
			String name = "D:\\java2404code\\Test\\a.txt";
			InputStream	is = new FileInputStream(name);
			
//			 int read() 读取字节信息,一个一个字节内容读取,读取到末尾返回值为-1
			int data1 = is.read();
			int data2 = is.read();
			int data3 = is.read();
			int data4 = is.read();
			int data5 = is.read();
			int data6 = is.read();
			
			System.out.println(data1);//97
			System.out.println(data2);//98
			System.out.println(data3);//99
			System.out.println(data4);//100
			System.out.println(data5);//101
			System.out.println(data6);//-1
			
            //循环读取
			int data = -1;
			while ((data = is.read())!=-1) {
				System.out.print((char)data);//abcde
			}
			
			//读取方式2:
			//int read(byte b[]) 每次读取数组b长度个字节,存在byte字节数组b中,读到末尾返回-1
			byte[] b = new byte[5];
			int len;
			while ((len = is.read(b))!=-1) {
				System.out.println(new String(b,0,len));
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

1.3 BufferedInputStream

BufferedInputStream是缓冲输入流。它继承于FilterInputStream。BufferedInputStream的作用是为另一个输入流添加一些功能,例如,提供“缓冲功能”以及支持“mark()标记”和“reset()重置方法”。
BufferedInputStream本质上是通过一个内部缓冲区数组实现的。例如,在新建某输入流对应的BufferedInputStream后,当我们通过read()读取输入流的数据时,BufferedInputStream会将该输入流的数据分批的填入到缓冲区中。每当缓冲区中的数据被读完之后,输入流会再次填充数据缓冲区;如此反复,直到我们读完输入流数据位置。

构造方法:

//			public BufferedInputStream(InputStream in)
			FileInputStream fis = new FileInputStream("D:\\java2404code\\Test\\a.txt");
			BufferedInputStream bis =  new BufferedInputStream(fis);
 
//alt+shift+z try--catch快捷键
		//缓冲流的参数依然是字节数组,缓冲区的大小为8192的字节数组
		try {
			FileInputStream fis = new FileInputStream("D:\\java2404code\\Test\\a.txt");
			BufferedInputStream bis =  new BufferedInputStream(fis);
			
			//读取
			byte[] buf = new byte[1024];
			int len;
			
			//循环的读取
			while ((len = bis.read(buf))!=-1) {
				System.out.println(new String(buf,0,len));
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

BufferedInputStream的作用是为其它输入流提供缓冲功能。创建BufferedInputStream时,我们会通过它的构造函数指定某个输入流为参数。BufferedInputStream会将该输入流数据分批读取,每次读取一部分到缓冲中;操作完缓冲中的这部分数据之后,再从输入流中读取下一部分的数据。
为什么需要进行缓冲读取呢?原因很简单,效率问题!缓冲中的数据实际上是保存在内存中,而原始数据可能是保存在硬盘或NandFlash等存储介质中;而我们知道,从内存中读取数据的速度比从硬盘读取数据的速度至少快10倍以上。

1.4 小结

●Java标准库的java.io.InputStream定义了所有输入流的超类:
        ○FileInputStream实现了文件流输入;
        ○BufferedInputStream使用缓冲区提高文件的读取效率;
        ○ByteArrayInputStream在内存中模拟一个字节流输入;
●总是使用try(resource)来保证InputStream正确关闭。

2. OutputStream字节输出流

InputStream是Java标准库提供的用于读取操作的输入流,而OutputStream是Java标准库提供的用于写入操作的基础输出流。和InputStream类似,OutputStream也是抽象类,它是所有输出流的超类。这个抽象类定义的一个最重要的方法就是void write(int b)。

2.1 构造方法

构造方法1:

public FileOutputStream(String name)
 //路径一定要存在,文件可以不存在
		//构造方法1:FileOutputStream(String name)
		OutputStream os=new FileOutputStream("D:\\java2404code\\Test\\aa.txt");
	    System.out.println(os);

构造方法2:

public FileOutputStream(File file)
//构造方法2:    public FileOutputStream(File file)
	    File f1=new File("D:\\java2404code\\Test\\aa.txt");
		OutputStream os1=new FileOutputStream(f1);
	    System.out.println(os1);

构造方法3:

public File0utputstream(string name,boolean b)
//构造方法3:File0utputstream(string name,boolean b)
		//追加写的方式
		OutputStream os = new FileOutputStream("D:\\java2404code\\Test\\aa.txt",true);

构造方法4:

public Fileoutputstream(File file,boolean b)
//构造方法4:public Fileoutputstream(File file,boolean b)
		//追加写的方式
		File f1 =  new File("D:\\java2404code\\Test\\aa.txt");
		OutputStream os1 = new FileOutputStream(f1,true);

2.2 写入

write(byte[] b);
write(int data);
write(byte[] b,int offer,int lenth);

●方法1:write(int data) 写出字节数据,每次写出一个字节信息

try {
			OutputStream os = new FileOutputStream("D:\\java2404code\\Test\\aa.txt");
			//方法1:write(int data) 写出字节数据,每次写出一个字节信息
			os.write(97);
			os.write(98);
			os.write(99);
			os.write('d');
			os.write('e');
			
	
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

●方法2:写出字节数组write(byte b[])

try {
			OutputStream os = new FileOutputStream("D:\\java2404code\\Test\\aa.txt");
			//方法2:写出字节数组write(byte b[])
			byte[] b= "还想继续考研".getBytes();//字符串的内容转换成字节数组
			//写出
			os.write(b);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

●方法3:写出字节数组,从指定小标开始写出,写出指定长度个字节信息

try {
			OutputStream os = new FileOutputStream("D:\\java2404code\\Test\\aa.txt");

			//方法3:写出字节数组,从指定小标开始写出,写出指定长度个字节信息
			//write(byte b[],int off, int len)
			byte[] b1= "还想继续考研".getBytes();//字符串的内容转换成字节数组
			//写出
			os.write(b1,0,15);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

换行:

try(FileOutputStream fos = new FileOutputStream("a.txt")){
			//从系统中获取换行符
			String str =System.lineSeparator();
			//写出字节数组中的内容
			fos.write("你好吗\r\n".getBytes());
			fos.write(("我很好"+str).getBytes());
			fos.write(("谢谢你"+str).getBytes());
		}catch(IOException e) {
			e.printStackTrace();

2.3 BufferedOutputStream

BufferedOutputStream这个类其实很简单,主要是里面包含了一个8192个字节的缓冲区。new BufferedOutputStream(OutputStream out)这个构造函数默认分配的就是8192个字节的byte[]数组(即缓冲区),如果要自己分配缓冲区大小可以调用构造函数new BufferedOutputStream(OutputStream out, int size)。

构造方法:

// public BufferedOutputStream(OutputStream out)
String name = "b.txt";
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(name))
String name = "b.txt";
		try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(name))) {
			bos.write("还想继续考研".getBytes());
			bos.write("还想继续考研2".getBytes());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

BufferedOutputStream的基本使用步骤如下:
1、创建FileOutputStream(字节输出流)对象,构造方法中绑定要输出的目标文件对象
2、创建BufferedOutputStream对象,构造方法中传递FileOutputStream对象,提高FileOutputStream的写入效率
3、使用BufferedOutputStream对象中的方法write()方法,把数据写入到内部缓冲区中
4、使用BufferedOutputStream对象中的flush()方法,把内部缓冲区的数据,刷新到文件中
5、使用BufferedOutputStream对象中的close()方法,释放资源(会先调用flush()方法刷新数据,第4步可以省略)

public class Main{
    public static void main(String[] args) throws IOException {
        try (FileOutputStream fos = new FileOutputStream("C:\\test\\buffered.txt");
				BufferedOutputStream bos = new BufferedOutputStream(fos)) {
			bos.write("天王盖地虎".getBytes());
            bos.flush();
            bos.write("宝塔镇河妖".getBytes());
		}
    }
}

2.4 实现文件的复制

public static void main(String[] args) {
		File f1 = new File("D:\\java2404code\\Test\\垃圾站.png");
		File f2 = new File("D:\\java2404code\\Test\\copy.png");
		fileCopy(f1, f2);
		File f3 = new File("D:\\java2404code\\Test\\copy1.png");
		fileCopy(f3);

	}

	/**
	 * 文件的复制
	 * 
	 * @param source 输入
	 * @param target 输出
	 */
	public static void fileCopy(File source, File target) {
		// 输入流和输出流对象
		try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(source));
				BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(target))) {

			// read(byte[])
			// 存放每次读取到的信息
			byte[] buff = new byte[1024];
			int len;// 记录每次读取到的长度

			// 循环读 -- 写出
			while ((len = bis.read(buff)) != -1) {
				// 将读取到的内容写出
				bos.write(buff, 0, len);
			}
			System.out.println("写出结束");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public static void fileCopy(File target) {
		URLConnection connection;
		try {
			URL url = new URL("https://ts1.cn.mm.bing.net/th/id/R-C.b8e84a0907bf9b5128dfa48be0ae48af?rik=tfH6k%2fT3hkauqw&riu=http%3a%2f%2fwww.08lr.cn%2fuploads%2fallimg%2f220330%2f1-2300141M0.jpg&ehk=dR6hTo1o7lNsHkpE62oIzMtJ%2bmxktf7%2fx6tp3Zt2uB8%3d&risl=&pid=ImgRaw&r=0");
			connection = url.openConnection();
			try(
			InputStream is = connection.getInputStream();
			BufferedInputStream bis= new BufferedInputStream(is);
			BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(target));){
				byte[] buff = new byte[1024];
				int len;
				
				while ((len = bis.read(buff))!=-1) {
					bos.write(buff,0,len);
				}
				System.out.println("下载完成");
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

2.5 小结

●Java标准库的java.io.OutputStream定义了所有输出流的超类:
        ○FileOutputStream实现了文件流输出;
        ○BufferedOutputStream可以使用缓冲区对文件进行写入操作;
●某些情况下需要手动调用OutputStream的flush()方法来强制输出缓冲区
●总是使用try(resource)来保证OutputStream正确关闭

3. Writer字符输出流

Reader是带编码转换器的InputStream,它把byte转换为char,而Writer就是带编码转换器的OutputStream,它把char转换为byte并输出。
Writer和OutputStream的区别如下:

OutputStream

Writer

字节流,以byte为单位

字符流,以char为单位

写入字节(0~255):void write(int b)

写入字符(0~65535):void write(int c)

写入字节数组:void write(byte[] b)

写入字符数组:void write(char[] c)

无对应方法

写入String:void write(String s)

3.1 构造方法

构造方法1:

//构造方法1:public FileWriter(String path);
		Writer w1 = new FileWriter("c.txt");

构造方法2:

//构造方法2:public FileWriter(File f1);
		Writer w2 = new FileWriter(new File("d.txt"));

构造方法3:

//构造方法3:public FileWriter(String path,boolean append);
		Writer w3 = new FileWriter("e.txt", true);

构造方法4:

//构造方法4:public FileWriter(File f1,boolean append); 
		Writer w4 = new FileWriter(new File("c.txt"), true);

3.2 一些方法

Writer是所有字符输出流的超类,它提供的方法主要有:
○写入一个字符(0~65535):void write(int c);
○写入字符数组的所有字符:void write(char[] c);
○写入String表示的所有字符:void write(String s)。

●void flush(); 刷新输出流并强制任何缓冲数据的字符被输出到目标位置

●void close();//调用close方法的时候,底层会把缓冲区中的数据写出到目标位置。

// 创建字符输出流对象 8192字节缓冲区
		Writer w1 = new FileWriter("a.txt");
		// void write(int data);//写出一个int值或者字符 的数据
		w1.write('中');
		w1.write('b');
		w1.write(97);
		// void flush(); 刷新输出流并强制任何缓冲数据的字符被输出到目标位置
		w1.flush();
		//void close();//调用close方法的时候,底层会把缓冲区中的数据写出到目标位置。
		//w1.close();
		w1.write('c');
		System.out.println("写出结束");
Writer w1 = new FileWriter("b.txt");
		
		for (int i = 0; i < 8192; i++) {
			w1.write('a');
		}
		w1.write('b');
		w1.close();
		
		System.out.println("写出完毕");

●void write(char[] array,int offset,int len);

●void write(String str,int offset,int len);

try (Writer w1 = new FileWriter("c.txt")) {
			w1.write("我想考研".toCharArray());
			char[] array= {'你','吃','了','吗'};
			w1.write(array,0,4);
			w1.write("还想继续考研");
			w1.write("我不想上班hahah",0,5);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

3.3 BufferedWriter 

BufferedWriter 是 针对 字符 输出 流的 缓 冲流 对象 ,在 字 符输 出缓 冲流 中可 以使用newLine() ;方法实现换行处理。

构造方法:

//public BufferedWriter(Writer out)
BufferedWriter bw = new BufferedWriter(new FileWriter("d.txt"))
	try (BufferedWriter bw = new BufferedWriter(new FileWriter("d.txt"))) {
			bw.write("还是想考研");
			bw.newLine();//换行
			bw.write("还想继续考研");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

4. Reader 字符输入流

见Java基础21

  • 25
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冯诺依曼转世

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值