JAVA IO

02【Java的IO模型】_java io包是属于哪种io模型 如果连接大多是长连接,则会导致连接无法释放,新的请求将无法得到处理,另外,BIO这种一个请求对应一个线程的方式在应对高并发的情况下,服务器必须也要创建同等量的线程来处理客户端的请求,这样对系统的消耗是非常大的;在NIO模型中,每个请求都会有一个与服务器做数据交互的通道(Channel),所有的通道都被注册到一个选择器中(selector),当需要与服务器做数据交互时,数据通过管道写入到一个缓冲区(Buffer)中,服务器通过往缓冲区中读取数据,如果当前通道没有数据时,就什么都不会获取, 阅读详情
一、关于Java IO的概述

  • IO流用来处理设备之间的数据传输
  • Java对数据的操作是通过流的方式
  • Java用于操作流的对象都在IO包中
  • IO流按照流向划分为输入流、输出流
  • IO流按照操作数据划分为字符流(专门处理文字)、字节流
我理解的程序处理数据过程大致如下:

二、File相关操作

一个File类的实例代表一个文件或文件夹,File.pathSeparator指的是分隔连续多个路径字符串的分隔符,File.separator才是用来分隔同一个路径字符串中的目录的。由于java可跨平台,所以当new一个File时,路径中的“;"和"/"要用File.pathSeparator和File.separator代替。

File常用的构造方法

import java.io.File;

public class IOTest {
	public static void main(String[] args) {
		File file1=new File("D:"+File.separator+"IOTest.Java");//文件绝对路径
		File file2=new File("D:"+File.separator+"IO");//目录的绝对路径
		File file3=new File(file2, "IOTest.java");//第一个参数File实例代表一个目录file2,第二个参数为file2目录内的文件名
		File file4=new File("D:"+File.separator+"IO", "IOTest.java");//目录和文件的字符串类型
		
	}
}
File的常用方法

	file1.createNewFile();
		System.out.println("file1.isFile():  " + file1.isFile());
		System.out.println("file1.isDirectory():  " + file1.isDirectory());
		System.out.println("file1.getName():  " + file1.getName());
		System.out.println("file1.getAbsolutePath  " + file1.getAbsolutePath());
		file2.mkdir();
		System.out.println("file2.isDirectory():  " + file1.isDirectory());
		String[] list = file2.list();//返回String[]类型的文件 只含文件名
		File[] listFile=file2.listFiles();//返回File[]类型的文件 包含完整的文件对象


其他相关方法的总结如下:

  • String getName():返回文件名或路径名(若是路径,返回最后一级子路径名)
  • String getPath():返回对象对应的路径名
  • File  getAbsoluteFile():返回绝对路径
  • String getAbsolutePath():返回对象对应的绝对路径
  • String getParent():返回文件目录的上一级目录名
  • boolean renameTo(File newName):重命名此File对象对应的文件或目录,若重命名成功返回true;
  • boolean exists():判断对象对应的文件或目录是否存在;
  • boolean canWrite():判断对象对应文件或目录是否可写;
  • boolean canRead():判断对象对应文件或目录是否可读;
  • boolean isFile():判断对象是文件,不是目录;
  • boolean isDirectory()  判断对象的文件是否是一个目录; 
  • boolean isAbsolute() 判断对象对应文件或目录是否为绝对路径名; 
  • boolean createNewFile() 当且仅当不存在,该方法创建一个该File对象所指定的新文件,创建成功返回true。 
  • boolean delete():删除File对象所对应的文件或路径;
  • boolean mkdir() 创建File对象所对应的目录,调用该方法的File对象必须对应路径,而不是文件。
  • String[] list():列出File对象的所有子文件名和路径名。
  • File[] listFiles():列出File对象的所有子文件和路径。
  • static File[] listRoots():列出系统所有的根路径;
对文件的操作前要判断文件是否存在,再做进一步io操作。


练习列出一个目录下所有文件及目录(利用递归):

public class IOTest {
	public static void main(String[] args) throws Exception {
	
		File file = new File("C:\\Users\\Mr\\Desktop\\源码");
		scan(file);

	}

	private static void scan(File file) {
		// TODO Auto-generated method stub
		File[] files = file.listFiles();
		for (int i = 0; i < files.length; i++) {
			File newfile = files[i];
			if (newfile.isFile()) {
				System.out.println("文件:" + newfile.getName());
			} else {
				System.out.println("目录:" + newfile.getName());
				scan(newfile);
			}
		}
	}
}

文件过滤器,根据文件名或路径获得想要的文件对象

	private static void scan(File file) {
		// TODO Auto-generated method stub
		File[] files = file.listFiles(new FilenameFilter() {

			@Override
			public boolean accept(File dir, String name) {
				// TODO Auto-generated method stub
				return name.contains(".java");
			}
			
		});
		System.out.println(Arrays.toString(files));

	}
通过listfile方法传入一个FilenameFilter接口的实例,复写accept方法,控制想要得到的文件。

三、流

  • 字符流

FileReader(直接读取)

import java.io.File;
import java.io.FileReader;

public class FileReaderTest   {
	public static void main(String[] args) throws Exception{
		File file=new File("d:"+File.separator+"test4.txt");
		FileReader reader=new FileReader(file);
		int ch=0;
		while((ch=reader.read())!=-1){
			System.out.print((char)ch);
		}
		reader.close();
	}
}

利用字符数组读取以提高效率

import java.io.File;
import java.io.FileReader;

public class FileReaderTest {
	public static void main(String[] args) throws Exception {
		File file = new File("d:" + File.separator + "test4.txt");
		FileReader reader = new FileReader(file);
		char[] buf = new char[1024];
		int len = 0;
		while ((len = reader.read(buf)) != -1) {
			System.out.print(new String(buf, 0, len));
		}
		reader.close();
	}
}

FileWriter(现有文件追加一行)

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

public class FileWriterTest {
	public static void main(String[] args) throws Exception{
		File file = new File("d:" + File.separator + "test4.txt");
		if(!file.exists())file.createNewFile();
		FileWriter writer=new FileWriter(file,true);//可追加设为true
		writer.write("\r\n-------新追加一行--------");
		writer.close();
	}
}

文本文件复制

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;

public class Copy {
	public static void main(String[] args) throws Exception {
		File source = new File("d:" + File.separator + "test4.txt");
		File target = new File("d:" + File.separator + "test5.txt");
		if (!target.exists())
			target.createNewFile();
		FileReader reader = new FileReader(source);
		FileWriter writer = new FileWriter(target, true);
		char[] buf = new char[1024];
		int len = 0;
		while ((len = reader.read(buf)) != -1) {
			writer.write(buf, 0, len);
			writer.flush();
		}
		writer.close();
		reader.close();
	}
}

  • 字符缓冲流
BufferedReader

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;

public class BufferedReaderTest {
	public static void main(String[] args) throws Exception {
		BufferedReader reader=new BufferedReader(new FileReader("d:" + File.separator + "test4.txt"));
		String line;
		while((line=reader.readLine())!=null){
			System.out.println(line);
		}
	}
}

BufferedWriter

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;

public class BufferedWriterTest {
	public static void main(String[] args) throws Exception {
		BufferedWriter writer=new BufferedWriter(new FileWriter("d:" + File.separator + "test5.txt",true));
		writer.newLine();
		writer.write("新追加一行");
		writer.flush();
		writer.close();
	}
}


文本文件复制(字符缓冲流)

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;

public class CopyByBuf {
	public static void main(String[] args) throws Exception {

		File source = new File("d:" + File.separator + "test4.txt");
		File target = new File("d:" + File.separator + "test6.txt");
		if (!target.exists())
			target.createNewFile();
		BufferedReader reader = new BufferedReader(new FileReader(source));
		BufferedWriter writer = new BufferedWriter(new FileWriter(target));
		String line;
		while ((line = reader.readLine()) != null) {
			writer.write(line);
			writer.newLine();
			writer.flush();
		}
		writer.close();
		reader.close();
	}
}

BufferedReader的子类LineNumberReader.setLineNumber(0)来设置初始行,默认0,getLineNumber()返回行号。

public class BufferedReaderTest {
	public static void main(String[] args) throws Exception {
		LineNumberReader reader=new LineNumberReader(new FileReader("d:" + File.separator + "test4.txt"));
		String line;
		//reader.setLineNumber(0);
		while((line=reader.readLine())!=null){
			System.out.println(reader.getLineNumber()+line);
		}
	}
}

  • 字节流
FileInputStream直接读取

public class FileInputStreamTest {
	 public static void main(String[] args) throws Exception {
	 FileInputStream in = new FileInputStream("d:" + File.separator + "test4.txt");
		int ch = 0;
		while ((ch = in.read()) != -1) {
			System.out.print((char) ch);
		}
		in.close();
	}
}	
FileInputStream通过byte[]读取
public class FileInputStreamTest {
	
	public static void main(String[] args) throws Exception {
		FileInputStream in = new FileInputStream("d:" + File.separator + "test4.txt");
		byte[] buf = new byte[1024];
		int len = 0;
		while ((len = in.read(buf)) != -1) {
			System.out.print(new String(buf, 0, len));
		}
 		in.close();
	}
}	
FileOutputStream直接写入数据
public class FileInputStreamTest {
	public static void main(String[] args) throws Exception {
	FileOutputStream out=new FileOutputStream("d:" + File.separator + "test.txt");
	out.write("黑马你好".getBytes("UTF-8"));
	out.close();
 }
}
FileOutputStream和FileInputStream通过byte[]图片
public class FileInputStreamTest {
	public static void main(String[] args) throws Exception {
	FileInputStream in = new FileInputStream("d:" + File.separator + "heima.jpg");
	FileOutputStream out=new FileOutputStream("d:" + File.separator + "heima_copy.jpg");
	byte[] buf = new byte[1024];
	int len = 0;
	while ((len = in.read(buf)) != -1) {
		out.write(buf, 0, len);
	}
	in.close();
	out.close();
}
}	
FileOutputStream和FileInputStream通过BufferedOutputStream和BufferedInputStream复制图片
public class FileInputStreamTest {
	public static void main(String[] args) throws Exception {
		BufferedInputStream in=new BufferedInputStream(new FileInputStream("d:" + File.separator + "heima.jpg"));
		BufferedOutputStream out=new BufferedOutputStream(new FileOutputStream("d:" + File.separator + "heima_copy1.jpg"));
		int data = 0;
		while ((data = in.read()) != -1) {
			out.write(data);
		}
		in.close();
		out.close();
	}
}

  • 转换流
System.out:对应的是标准输出设备,控制台。
System.in:对应的标准输入设备:键盘。
而它们都是属于字节流,现在要实现对控制台输入的字符串打印或其他操作,由于是对文本进行操作,FileReader和FileWriter更为方便,怎样将要操作的字节流转换为字符流然后进行操作呢?这里可以用转换流InputStreamReader和OutputStreamReader:
package Blog;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class ConsoleTest {
	public static void main(String[] args) throws Exception {
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				System.in));
		BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
				System.out));
		String line = null;
		while (!"stop".equals(line) && (line = reader.readLine()) != null) {
			writer.write(line);
			writer.newLine();
			writer.flush();
		}
		writer.close();
		reader.close();
	}
}
  • 字符流与字节流的总结
字节流和字符流在处理数据时代码和流程大致相同,字符流其根本也是用的字节流,但是为了处理文字方便加入了类似缓冲块的概念,使其字符流可以对文字的编码进行操作,避免乱码的出现,正因为有了缓冲,所以每次写入后需要flush操作将其刷进目标中,而字节流则不需要。并且字符流读取后close方法时也会对缓冲区进行刷新操作。字符流和字节流两者相比,字节流通用可以处理任何类型数据,但处理处理文本时,由于字符流的编码特性是最为合适的,并且字符流提供了专门处理文本的方便方法,而处理非文本时,一定要使用字节流,如果使用字符流可能复制成功后文件仍无法读取。
  • 用流对目录复制
将C盘下目录复制到D盘
package Blog;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class CopyDir {
	public static void main(String[] args) throws Exception {
		File dir_s = new File("c:" + File.separator + "heima");//源目录
		File dir_d = new File("d:" + File.separator + dir_s.getName());//目标目录
		dir_d.mkdir();//创建目录
		DoCopy(dir_s, dir_d);
	}

	private static void DoCopy(File dir_s, File dir_d) throws Exception {
		// TODO Auto-generated method stub

		File[] files = dir_s.listFiles();
		for (File file : files) {
			if (file.isFile()) {//如果是文件 复制
				BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
				File file_new=new File(dir_d, file.getName());
				file_new.createNewFile();
				BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file_new));
				int data = 0;
				while ((data = in.read()) != -1) {
					out.write(data);
				}
				in.close();
				out.close();
			} else {//如果是目录 递归
				File dir_new=new File(dir_d,file.getName());
				dir_new.mkdir();
				DoCopy(file,dir_new);//
			}
		}
	}

}
输入两个目录,作为源和目的,将源目录中所有.java文件复制到目的目录中同时将扩展名修改为txt
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;



public class Copy {
	
	public static void main(String[] args) throws Exception {
		System.out.println("请输入一个源目录");
		String SourceDir = getDir();
		System.out.println("请输入一个目的目录");
		String dtDir = getDir();
		mainJob(SourceDir, dtDir);
		System.out.println("-------------已完成-------------");
	}

	static String getDir() throws Exception {
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				System.in));
		String str = reader.readLine();
		//reader.close();
		return str;
	}

	static void mainJob(String S, String D) throws Exception {
		File source = new File(S);
		File dest = new File(D);
		dest.mkdir();
		List<File> javaList = new ArrayList<File>();
		javaList = scanDir(source, javaList);
		for (File file : javaList) {
			File newFile = new File(dest,FileUtil.getHeadName(file)+".txt");
			int n = 0;
			String head=FileUtil.getHeadName(newFile);
			String tail=FileUtil.getExtendName(newFile);
			while (newFile.exists()) {
				//判断 若有同名文件出现时 防止覆盖
				newFile=new File(dest,head+"("+(++n)+")."+tail);
			}
			newFile.createNewFile();
			copy2dest(file, newFile);

		}

	}

	/**
	 * @param source
	 * @param javaList
	 * @return
	 * @throws Exception
	 * 扫描目录筛选java文件   返回File集合
	 */
	static List<File> scanDir(File source, List<File> javaList)
			throws Exception {
		File[] javas = source.listFiles();
		for (File file : javas) {
			if (file.isDirectory()) {
				scanDir(file, javaList);
			} else {
				if (file.getName().endsWith(".java"))
					javaList.add(file);
			}
		}
		return javaList;

	}

	/**
	 * @param file
	 * @param dest
	 * @throws Exception
	 * 主要复制动作
	 */
	static void copy2dest(File file, File dest) throws Exception {
		BufferedInputStream in = new BufferedInputStream(new FileInputStream(
				file));
		BufferedOutputStream out = new BufferedOutputStream(
				new FileOutputStream(dest));
		int data = 0;
		System.out.println("正在复制  "+dest.getName());
		while ((data = in.read()) != -1) {
			out.write(data);
		}
		in.close();
		out.close();

		 
	}
	
	
 
}
/**
 * @author Mr
 *	自定义文件工具类
 */
class FileUtil{
	/**
	 * @param file
	 * @return
	 * 获取文件名不带扩展名
	 */
	public static String getHeadName(File file){
		return file.getName().substring(0,file.getName().lastIndexOf("."));
	}
	/**
	 * @param file
	 * @return
	 * 获取扩展名
	 */
	public static String getExtendName(File file){
		
		return file.getName().substring(file.getName().lastIndexOf(".")+1);
	}
	/**
	 * @param file
	 * @param extendName
	 * @return
	 * 修改扩展名
	 */
	public static File trExtendName(File file,String extendName){
		return new File(file.getParent(),getHeadName(file)+"."+extendName);
	}
}

四、其它重要IO相关

1.可接收字符输出流和字节输出流的打印流PrintWriter,PrintWriter功能十分强大也比较常用,同时可直接接受File类型文件或String文件路径,具有自动flush的特点。

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.PrintWriter;

public class PrintWriterTest  {
	public static void main(String[] args) throws Exception{
		BufferedReader reader=new BufferedReader(new FileReader("d:" + File.separator + "test4.txt"));
		PrintWriter printer=new PrintWriter(System.out,true);//true 自动刷新, system.out是输出流 也可以是文件File或文件路径
		String data=null;
		while((data=reader.readLine())!=null){
			printer.println(data);
		}
		printer.close();
		reader.close();
	}
}

2.通过InputStream下的SequenceInputStream类实现合并多个字节输入流

该类有两个构造方法,也就是两种不同的实现方式:

通过传入Enumeration<? extends InputStream>对多个流的封装

public class SequenceInputStreamTest {
	public static void main(String[] args) throws Exception {
		FileInputStream in1 = new FileInputStream("d:" + File.separator
				+ "test4.txt");
		FileInputStream in2 = new FileInputStream("d:" + File.separator
				+ "test5.txt");
		FileInputStream in3 = new FileInputStream("d:" + File.separator
				+ "test6.txt");
		Vector<InputStream> vector = new Vector<InputStream>();
		vector.add(in1);
		vector.add(in2);
		vector.add(in3);//将三个inputStream添加进Vector集合
		Enumeration<InputStream> enumeration = vector.elements();//获取Enumeration对象
		SequenceInputStream in_all = new SequenceInputStream(enumeration);
		PrintWriter printer = new PrintWriter(System.out, true);
		BufferedReader reader = new BufferedReader(
				new InputStreamReader(in_all));
		String data = null;
		while ((data = reader.readLine()) != null) {
			printer.println(data);
		}
		reader.close();
		in1.close();
		in2.close();
		in2.close();
		in_all.close();
		printer.close();
	}
}

传入两个inputStream实例对象,并且只能是两个,不常用

public class SequenceInputStreamTest {
	public static void main(String[] args) throws Exception {
		FileInputStream in1 = new FileInputStream("d:" + File.separator
				+ "test4.txt");
		FileInputStream in2 = new FileInputStream("d:" + File.separator
				+ "test5.txt");
		SequenceInputStream in_all = new SequenceInputStream(in1, in2);
		PrintWriter printer = new PrintWriter(System.out, true);
		BufferedReader reader = new BufferedReader(
				new InputStreamReader(in_all));
		String data = null;
		while ((data = reader.readLine()) != null) {
			printer.println(data);
		}
		reader.close();
		in1.close();
		in2.close();
		in_all.close();
		printer.close();
	}
}

3.切割流

public class SplitFile {
	public static void main(String[] args) throws Exception{
		BufferedInputStream in=new BufferedInputStream(new FileInputStream("d:" + File.separator + "梁心颐 - 小树.mp3"));
		BufferedOutputStream out=null;
		byte[] data=new byte[1024*1024];
		int len=0;
		int count=0;
		while((len=in.read(data))!=-1){
			out=new BufferedOutputStream(new FileOutputStream("d:" + File.separator + "梁心颐 - 小树"+(++count)+".part"));
			out.write(data, 0, len);
			out.close();
		}
		in.close();
	}
}

4.ObjectInputStream和ObjectOutStream实现对象持久化

要想通过该方法持久化的实例对象,该类必须实现Serializable接口

import java.io.Serializable;

public class Person implements Serializable{
	
	private static final long serialVersionUID = -4102534291757583600L;
	private String name;
	private Integer age;
	public String add;
	public Person(String name, Integer age, String add) {
		super();
		this.name = name;
		this.age = age;
		this.add = add;
	}
	public Person() {
		// TODO Auto-generated constructor stub
	}
}
并声明UID,如果不实现该接口则在ObjectOutputStream写出对象时会报“未序列化的对象”异常

下面开始对一个Person对象进行持久化即写入一个文件中,随后读出该文件

public class ObjectStream {
	public static void main(String[] args) throws Exception, IOException {
		Person p1=new Person("liuli", 25, "china");
		//写
		ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("D:"+File.separator+"test.obj"));
		out.writeObject(p1);
		out.close();
		//读
		ObjectInputStream in=new ObjectInputStream(new FileInputStream("D:"+File.separator+"test.obj"));
		Person p2=(Person)in.readObject();
		System.out.println(p2.getName()+p2.getAdd()+p2.getAge());
	}
}


5.管道流

public class PipeTest {
	public static void main(String[] args) throws Exception {
		PipedInputStream pipeIn = new PipedInputStream();
		PipedOutputStream pipeOut = new PipedOutputStream();
		pipeIn.connect(pipeOut);//连接两个流
		In in = new In(pipeIn);
		Out out = new Out(pipeOut);
		Thread t1 = new Thread(in);
		Thread t2 = new Thread(out);
		t1.start();
		t2.start();
	}
}

class In implements Runnable {
	private PipedInputStream in;

	public In(PipedInputStream in) {
		// TODO Auto-generated constructor stub
		this.in = in;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub

		BufferedReader reader = new BufferedReader(new InputStreamReader(in));
		String line = null;
		try {
			while ((line = reader.readLine()) != null) {
				System.out.println(line);
			}
			reader.close();
			in.close();

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();

		}
	}
}

class Out implements Runnable {
	private PipedOutputStream out;

	public Out(PipedOutputStream out) {
		// TODO Auto-generated constructor stub
		this.out = out;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		PrintWriter writer=new PrintWriter(out, true);
		try {
			writer.println("黑马程序员2015年1月9日18:51:42");
			writer.println("黑马程序员2015年1月9日18:51:45");
			writer.println("黑马程序员2015年1月9日18:51:47");
			writer.close();
			out.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
由此可见管道流建立了两个不同线程的沟通桥梁,可以实现线程间的通讯,可以实现生产者消费者模型。

6.DataInputStream和DataOutputStream存储基本数据类型数据

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class DataStream {
	public static void main(String[] args) throws Exception{
		DataOutputStream out=new DataOutputStream(new FileOutputStream("d:" + File.separator + "test.txt"));
		out.writeInt(2015);
		out.writeBoolean(true);
		out.writeDouble(2015.0109);
		out.close();
		
		DataInputStream in=new DataInputStream(new FileInputStream("d:" + File.separator + "test.txt"));
		System.out.println(in.readInt());
		System.out.println(in.readBoolean());
		System.out.println(in.readDouble());
		in.close();
	}
}

7.ByteArrayInputStream和ByteArrayOutputStream

public class ByteArrayOutputStreamTest {
	public static void main(String[] args) throws Exception {
		File file = new File("d:" + File.separator + "test4.txt");
		if (!file.exists())
			throw new RuntimeException("文件不存在");
		FileInputStream in;
		ByteArrayOutputStream arr = new ByteArrayOutputStream();

		in = new FileInputStream(file);
		byte[] data = new byte[5];
		int len = 0;

		while ((len = in.read(data)) != -1) {
			arr.write(data, 0, len);

		}
		System.out.println(arr.toString());
		in.close();
	}	
}	

8.StringReader和StringWriter
public class StringReader {
	public static void main(String[] args) throws Exception {
		
		BufferedReader reader2=new BufferedReader(new StringReader("黑马程序员"));
		StringWriter writer2=new StringWriter();
		writer2.append(reader2.readLine());
		writer2.append("------追加新文字");
		System.out.println(writer2.toString());
		
		BufferedReader reader3=new BufferedReader(new CharArrayReader("黑马程序员".toCharArray()));
		CharArrayWriter writer3=new CharArrayWriter();
		writer3.write(reader3.readLine().toCharArray());
		System.out.println(writer3.toString());
	}	
}	

9.CharArrayReader和CharArrayWriter

public class CharArray {
	public static void main(String[] args) throws Exception {
		BufferedReader reader3=new BufferedReader(new CharArrayReader("黑马程序员".toCharArray()));
		CharArrayWriter writer3=new CharArrayWriter();
		writer3.write(reader3.readLine().toCharArray());
		System.out.println(writer3.toString());
	}	
}

总结:ByteArrayInputStream和ByteArrayOutputStream、CharArrayReader和CharArrayWriter、StringReader和StringWriter都是用流的思想操作内存中的数据。








Java实战:使用Hutool中的FileUtil操作文件笔记 文件操作是每个项目中必备的一个模块,Hutool中的FileUtil类库封装了大多数文件操作,非常方便,今天给大家分享一下具体的使用示例。 阅读详情

相关推荐

FileUtil(文件操作工具类)

FileUtil(文件操作工具类)

javautil File文件,文件夹的创建,删除 以及文件_工具方法

java删除文件夹,文件夹下的文件

zona_wzq的博客 1018

告别环境依赖!用PyInstaller把PaddleOCR项目打包成独立EXE(附完整spec文件配置)

本文详细介绍了如何使用PyInstaller将PaddleOCR项目打包成独立EXE文件,彻底解决Python环境依赖问题。通过完整的spec文件配置和实战技巧,开发者可以轻松创建开箱即用的OCR工具,特别适合需要交付给非技术用户的场景。文章涵盖环境配置、模型打包、性能优化等关键环节,并提供了解决常见问题的方案。

weixin_33712987的博客 575

FileUtils 基本文件操作

FileUtils.cd( dir, *options ) FileUtils.cd( dir, *options ) {|dir| .... } Options: noop verbose移动到dir目录。若被用作迭代器的

方逸涛的专栏 1万+

Windows server 2012R2安装Oracle11g

打开 开始——所有程序——Oracle-OraDb11g_home1——配置和移植工具——Database Configuration Assistant。打开 开始——所有程序——Oracle-OraDb11g_home1——配置和移植工具——Net Configuration Assistant。首先打开Oracle的安装位置找到下面的位置找到tnsnames.ora文件右键编辑。打开Oracle的安装位置找到下面的位置找到tnsnames.ora文件右键编辑。选择仅安装数据库软件。

qq_74770105的博客 3596

解决方案:“Project1.exe”(Win32): 已加载“C:\Windows\SysWOW64\KernelBase.dll”。无法查找或打开 PDB 文件。

解决方案:“Project1.exe”(Win32): 已加载“C:\Windows\SysWOW64\KernelBase.dll”。无法查找或打开 PDB 文件。 添加getchar();代码块解决无法查找或打开PDB文件。 错误提示: “Project1.exe”(Win32): 已加载“C:\Windows\SysWOW64\ntdll.dll”。无法查找或打开 PDB 文件。 “Pro...

m0_46523403的博客 6421

java.util.File 中,mkdir()方法和mkdirs()方法的区别

首先我们看一下这两个方法在API中的解释: mkdir():创建此抽象路径名指定的目录。 mkdirs():创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。注意,此操作失败时也可能已经成功地创建了一部分必需的。 也就是说,mkdir()只能创建一级的目录,且需要存在父目录;mkdirs()可以创建多级目录,无论是否存在父目录 可以用代码简单测试一下 //当我们在D盘根目录下

wer的博客 3995

银河麒麟操作系统最佳实践专栏介绍

本专栏聚焦国产银河麒麟操作系统(桌面版/服务器版)的实战应用,提供系统安装、配置优化、应用部署、故障排查等实用指南。内容基于真实操作场景,涵盖Linux通用技术(如RAID配置、环境变量管理)、服务器系统专项(如数据库迁移、驱动安装、安全加固)及桌面系统技巧(如PXE安装、镜像封装)。面向IT运维、开发者和国产化转型人员,突出实战性和差异化,帮助用户规避常见问题,提升系统管理效率。所有教程均配有详细步骤和截图,确保可操作性,并持续更新适配新版系统。

信创运维工程师 · 银河麒麟 & 容器实战 | 金融生产环境迁移·等保加固 | 142篇原创·17万+阅读 534

Hutool Java工具类库-FileUtil(文件工具类)

Hutool的FileUtil几乎涵盖了所有常见的文件操作场景,且方法设计简单直观,可以显著减少Java文件操作相关的样板代码。建议在实际使用时结合Hutool的其他工具类(如IoUtil、CharsetUtil等)以获得更好的开发体验。

lengxia0的博客 2441

11.嵌入式控制器EC实战 KBC矩阵键盘Keyboard开发流程

文章目录笔记本矩阵键盘概述矩阵键盘的扫描方式行列扫描方式逐行逐列扫描方式EC中矩阵键盘是如何扫描并得到码值的(代码分析) 笔记本矩阵键盘概述 在EC中支持两种形式的键盘,一种是PS/2接口的键盘,这种键盘几乎已经被USB接口的键盘所取代,所以PS/2接口的键盘不在我们的讨论范围。 另一种键盘则是矩阵键盘,也是笔记本电脑的内置键盘,该键盘类似于学习单片机时使用的4*4的那种键盘,笔记本使用的矩阵键盘有三种规格,分别是16*8、17*8和18*8。16、17和18代表着该款键盘的列数,8代表着键盘的行数,我们这

qq_30135687的博客 3810

永磁同步电机MTPA控制详解:从理论到实践的全方位指南

永磁同步电机(PMSM)凭借其高功率密度卓越的效率以及精准的控制性能,已在工业驱动、电动汽车和家用电器等领域获得广泛应用。而在PMSM的诸多控制策略中,最大转矩电流比(MTPA)控制因其能显著提升电机效率而占据核心地位。在输出特定转矩时,通过优化直轴电流(Id)和交轴电流(Iq)的分配,使定子电流的幅值最小化。对于电机测试工程师而言,理解MTPA意味着掌握了一把提升系统性能的关键钥匙。为什么这一点如此重要?因为定子电流的减小直接带来了铜损的降低。

优快云-新能源汽车研发测试专业博主 520

import java.io 是什么意思_Java IO 详解

Java IO 详解初学java,一直搞不懂java里面的io关系,在网上找了很多大多都是给个结构图草草描述也看的不是很懂。而且没有结合到java7 的最新技术,所以自己来整理一下,有错的话请指正,也希望大家提出宝贵意见。首先看个图:(如果你也是初学者,我相信你看了真个人都不好了,想想java设计者真是煞费苦心啊!)这是java io 比较基本的一些处理流,除此之外我们还会提到一些比较深入的基于i...

weixin_34304274的博客 1万+

基于STM32L4XX、HAL库的ESP32-C3-WROOM-02-N4 WIFI模块驱动程序设计

支持802.11 b/g/n Wi-Fi (2.4GHz)RISC-V 32位单核处理器,主频高达160MHz。封装尺寸:18mm × 20mm × 3mm。工作温度范围:-40°C ~ 85°C。// 设置WiFi模式为STA。支持Bluetooth 5 (LE)// 发送AT指令测试通信。// 检查响应是否包含OK。内置4MB SPI Flash。// 连接TCP服务器。// 发送HTTP请求。// 初始化UART。// 建立TCP连接。低功耗设计,适合IoT应用。

zhusl6688的博客 385

Java 中的阻塞 IO 和非阻塞 IO

IO(输入输出)操作是一个基础而又关键的部分。在 Java 中,处理 IO 通常涉及到阻塞 IO 和非阻塞 IO 两种模式。本文将介绍这两种模式的概念、特点以及在 Java 编程中的应用场景与区别。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 5871

32、运算放大器的工作原理与应用

本文详细介绍了运算放大器的工作原理与多种应用场景,涵盖开环与闭环放大器的基本概念、理想运算放大器的特性及其‘黄金规则’。文章深入解析了反相放大器、同相放大器、单位增益跟随器与反相器的配置和增益计算,并探讨了电压比较器及窗口比较器的工作机制。同时提供了运算放大器在实际应用中的选型流程、使用注意事项以及常见故障排查方法,帮助读者全面掌握运算放大器的设计与应用要点。

u5v6w7的博客 164

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

彻底搞懂Java的网络IO

IO是Input/Output的缩写。Unix网络编程中有五种IO模型: blocking IO(阻塞IO) nonblocking IO(非阻塞IO) IO multiplexing(多路复用IO) signal driven IO(信号驱动IO) asynchronous IO(异步IO) 背景 java.io包基于流模型实现,提供Fil...

全菜工程师小辉的博客 4092

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

java io 阻塞io_Java IO流阻塞现状理解

Java线程的状态有五种.其中IO流操作一些接口是阻塞操作的例如package com.cqs.example.io.stream;import lombok.extern.slf4j.Slf4j;import java.util.Scanner;import java.util.concurrent.atomic.AtomicLong;/**** @Author lixw* @Date 7/22...

weixin_35433930的博客 973

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

java io

 Java IO       本篇主要讲述IO相关的内容,主要包括:与IO相关的简单的历史背景知识;Java IO的简单分类;与IO设计相关的两个模式;同时列举几个简单的例子;分析其中几个实现的源代码;最后给大家一些简单扩展的例子。治学先治史,下面我们先从简单的历史开始吧! 一、      历史背景       “对语言设计人员来说,创建好的输入/输出系统是一项特别困难的任务。

因为了解所以无知 3万+

Java IO 模型详解:从传统 IO 到异步 IO

IO 模型主要有五种:阻塞 I/O、非阻塞 I/O、多路复用、信号驱动和异步 I/O。阻塞 I/O:应用程序执行 I/O 操作时,会一直等待数据传输完成,期间无法执行其他任务。非阻塞 I/O:应用程序执行 I/O 操作时,如果数据未准备好,立即返回错误状态,不等待数据传输完成,可执行其他任务。多路复用:允许一个线程同时管理多个 I/O 连接,适用于高并发、低延迟和高吞吐量场景,减少线程数量和上下文切换开销。信号驱动。

专注Java和MySQL领域知识分享 1258

java IO操作

原文链接 [https://zhhll.com.cn/2020/java基础/IO/1.java基础之IO操作/] 用户进程发起请求,内核接收到请求后,从I/O设备中获取数据到buffer中,再将buffer中的数据copy到用户进程的地址空间,该用户进程获取到数据后再响应客户端。 数据输入到buffer需要时间,从buffer复制数据至进程也需要时间,根据在这两段时间内等待方式不同,I/O动作可分为五种模式 - 阻塞I/O - 非阻塞I/O - I/O复用 - 信号驱动I/O - 异步I/O

Lxn2zh的博客 1174

Java IO 教程,读完就能学会 Java IO 操作

Java IO(Input/Output)即 Java 的输入输出系统,是 Java 编程中用于处理数据传输的重要部分,它提供了一系列类和接口,让程序能够与各种数据源(如文件、网络连接、内存缓冲区等)进行数据的读取和写入操作。

ubuntulinuxjava的专栏 810

【Linux】Java文件IO之普通IO与Buffer IO

在Java中,输入输出(IO)操作是编程中一项重要的任务。无论是从外部文件中读取数据,还是向文件写入数据,或者是与用户进行交互,都需要用到IO操作。

morris 4万+

java——io

允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。如果类没有显示定义这个静态变量,它的值是Java运行时环境根据类的内部细节自动生成的。如果某个类的字段不是基本数据类型或 String 类型,而是另一个引用类型,那么这个引用类型必须是可序列化的,否则拥有该类型的 Field 的类也不能序列化。缓冲流要"套接"在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了一些新的方法。

zjx1415926的博客 1010

【IO】java IO流的类型及IO模型

本文详细介绍了IO流的几种类型以及它们使用的场景,同时介绍了常见的几种IO模型。

QiuYanping_的博客 874

Java IO 底层原理

引言 一提到 IO,就绕不开对 page cache(页缓存)的讨论,页缓存是操作系统为了提升磁盘读写性能在应用进程与磁盘之间加设的提供预读和异步刷盘机制的内核缓冲区。java 的 IO 操作是建立在操作系统的 IO 之上的,从最基础的 read/write 系统调用,到具有零拷贝特性的 sendfile、mmap,在 java 中都能看到它们的身影。本文的主要目的是纵观全局,鸟瞰 java IO 体系,并指出每种 IO 方式的特点与使用场景。整篇文章会围绕下图作分步讲解,为了简单起见,这里主要以写操作为例

海为龙世界,云是鹤家乡 2956
上一篇: JAVA 多线程
下一篇: JAVA 网络编程
SetO2
博客等级 码龄12年 5粉丝 12原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值