【Java】输入与输出与JDK1.5之后的新型字符串StringBuilder

输入与输出在Java里面相当基础,在Java各大书籍里面讲了又讲,但上面的概念往往讲得非常复杂,Java的老师强调学生必须透彻地弄得每一个类、每一个方法的意义,实际上,我们仅仅关注的是如何达到一个简单的输入输出效果。在网络上一个小小的Java输入输出包罗万象,主要是在JDK1.5推出了新型的Scanner输入,而以往的BufferedReader同样可以完成输入操作,也许多有经验的老手把自己使用惯的一套放上网络,根本不告诉别人怎么修改。下面举例子,彻底地说明白Java的输入输出,包括控制台,包括文件,其实根本就不难,完全是有迹可循。

一、基本目标

首先在C盘有个a.txt,里面存在一些内容

接着,我将写如下的一个Java小程序来说明Java的输入与输出,首先同时利用BufferReader与Scanner获取用户输入的一行东西,以说明两个方法的同理性,Scanner只不过是BufferReader的改进而已,其次利用Scanner获取用户输入的一堆东西,同时存放在一个动态数组ArrayList里面,方便以后操作,不是网上那种程序都不知道怎么操作这一堆东西。动态数组ArrayList不明白的,可以参考我之前写的《【Java】Java中的Collections类——Java中升级版的数据结构》(点击打开链接),最后把上面那个a.txt读取到Java中新型的字符串StringBuilder里面来,之后把字符串中的所有回车替换成空格,再输出到C盘的b.txt:

二、制作过程

1、首先是同时利用BufferReader与Scanner获取用户输入的一行东西,以说明两个方法的同理性,但做之前你必须在引入以下两个包:

import java.util.*;
import java.io.*;

Scanner在util里面,BufferReader在io里面,而且下面的动态数组什么的都需要这些,之后才开始工作:

public static void inputOneLine() throws IOException{
	//System.in实际上与System.out互相对应,
	//System.in是指用户在控制台的输入,System.out是值控制台的输出
	System.out.print("请输入一行东西:");
	String inputString="";
	//Scanner对System.in进行读取,nextLine()读取一行,也就是读到第一个回车为止
	inputString=new Scanner(System.in).nextLine();
	System.out.println("你输入的是:"+inputString);
	System.out.print("请输入一行东西:");
	//BufferedReader的readLine()同理
	inputString=new BufferedReader(new InputStreamReader(System.in)).readLine();
	System.out.println("你输入的是:"+inputString);
}

(1)值得注意的是,如果扫描器Scanner还有一个next()方法,这个方法是读到第一个分隔符位置,也就是如果遇到Tab、空格、回车,Scanner就会停止读写,而缓冲区读者BufferedReader同样有一个read()方法,这个方法只能读取一个字符,读完就停止了。

(2)缓冲区读者BufferedReader必须对输入流进行操作,也就是System.in必须被转换成一个输入流才能被缓冲区读者操作,扫描器Scanner则不用,可以之前对System.in操作,所以说Scanner是进步的

(3)Scanner里面还有nextInt();等方法,它是指如果用户输入的东西是整形int,就能自动返回这个int,不用再处理,一般没有人使用这些方法,因为要增加程序的容错性、健壮性,把所有东西都认为是字符串读进来,再进行是否数的判断,再转换为一个数。

2、其次利用Scanner获取用户输入的一堆东西,同时存放在一个动态数组ArrayList里面,方便以后操作。

public static void inputMultiLine(){
	//创建一个动态数组
	ArrayList<String> inputStringArr=new ArrayList<String>();
	System.out.println("请输入一堆东西,输入#结束");
	Scanner scanner=new Scanner(System.in);
	//这个循环不断继续,直到读进来的字符串是"#"才打断
	//由于Java中(好像不止是在Java,在不少语言都是),字符串是个对象,因此,只能使用equals方法判断
	//==,!=编译不出错,程序不错,但照样跑,因为对象与对象的==的意思是判断这两个是否都是String对象,不是这样的!
	while(true){
		String temp=scanner.nextLine();
		//如果字符串不是什么都没有,不是#
		if(!temp.equals("")&&!temp.equals("#")){
			//那么就把它压进动态数组
			inputStringArr.add(temp);
		}
		//如果是#则打断循环
		if(temp.equals("#")){
			break;
		}
	}
	System.out.println("刚才,你输入的东西为"+inputStringArr);
	//如果动态数组存在第二个函数,则把它取出并打印出来
	if(inputStringArr.size()>1){
		System.out.println("你输入的第二行为:"+inputStringArr.get(1));
	}
}

3、最后把上面那个a.txt读取到Java中新型的字符串StringBuilder里面来,之后把字符串中的所有回车替换成空格,再输出到C盘的b.txt。

这里其实把扫描器要扫描的东西,从System.in改成一个文件就行了,这个方法由于设置到文件的输入输出,所以要跑出IO异常,至于缓冲区的读者写者在之前的《【Java】打印流与缓冲区读者完成输入与输出到文件操作》(点击打开链接)做过了,这里不做了。

public static void fileInputOutput() throws IOException{
	//说明我要扫描c:\a.txt,在字符串的\必须转义成\	Scanner scanner=new Scanner(new File("c:\\a.txt"));
	StringBuilder filetoStringTemp=new StringBuilder("");
	//如果还有下一行的话?hasNext()方法不会导致扫描器Scanner的游标向下跳,因此可以作为判断条件
	//如果会向下跳就会出现隔行没有被读取的现象
	while(scanner.hasNext()){
		//StringBuilder没有重载运算符+=号,只能通过append()方法操作,同样的结果
		filetoStringTemp.append(scanner.next());
		//每读完一行,再补上一个换行,scanner不会把换行读进来
		filetoStringTemp.append("\n");
	}
	//把StringBuilder转换成String,同样也可以通过其toString实现。
	String filetoString=new String(filetoStringTemp);
	System.out.println(filetoString);
	//把所有回车换成空格,注意的是replaceAll是返回一个String,必须用来替换原来的字符串,
	//它不是一个void()方法,弄完就完事了
	filetoString=filetoString.replaceAll("\n", " ");
	System.out.println(filetoString);
	//判断这个字符串是否以"# "可以看到运行结果返回true,这方法在判断后缀名的时候很有用
	System.out.println(filetoString.endsWith("# "));
	//用打印流打印到文件,这里指定文件用文件写者来指定,这样就不会出现覆盖输出的问题了
	PrintWriter printwriter=new PrintWriter(new FileWriter("c:\\b.txt",true));
	//跟System.out.println()控制台输出方法有异曲同工之妙,只是我是输出到文件而已
	//把下面这行代码倒过来看你就能理解
	printwriter.println(filetoString);
	//必须关闭文件打印流才能完成一次输出,否则,打印的内容永远只在内存!
	printwriter.close();
	System.out.println("已经把字符串filetoString输出到c盘的b.txt里面了。");
}

(1)开始先用JDK1.5之后的新型字符串StringBuilder来不停地接受从文件读过来的东西。这个东西比String好,坦诚String同样可以接受字符串,程序还更短:

String a="";
a+="";

但是这样据说会多出很多临时变量让Java回收,效率不高,遇到一些超长的字符串,最好使用JDK1.5之后的新型字符串StringBuilder,这东西效率高,此外JDK1.5还新增了StringBuffer字符串,但这东西由于里面有线程互斥保护机制,所以效率没StringBuilder高,但如果出现多线程操作同一个字符串,使用StringBuffer你就不用写一段线程互斥的代码,线程互斥是什么,之前在《【Java】线程并发、互斥与同步》(点击打开链接)已经说过了。

(2)字符串里面还有indexof与substring的实用方法,曾经在《【Java】截取字符串中的首个图片地址》(点击打开链接)做过了,不再赘述。

三、总结与展望

于是,整个程序如下,在主函数调用上面的三个方法就能够直接执行了,这些方法必须定义为静态方法,才能被这样调用:

import java.util.*;
import java.io.*;

public class ScannerTest {
	public static void inputOneLine() throws IOException {
		// System.in实际上与System.out互相对应,
		// System.in是指用户在控制台的输入,System.out是值控制台的输出
		System.out.print("请输入一行东西:");
		String inputString = "";
		// Scanner对System.in进行读取,nextLine()读取一行,也就是读到第一个回车为止
		inputString = new Scanner(System.in).nextLine();
		System.out.println("你输入的是:" + inputString);
		System.out.print("请输入一行东西:");
		// BufferedReader的readLine()同理
		inputString = new BufferedReader(new InputStreamReader(System.in))
				.readLine();
		System.out.println("你输入的是:" + inputString);
	}

	public static void inputMultiLine() {
		// 创建一个动态数组
		ArrayList<String> inputStringArr = new ArrayList<String>();
		System.out.println("请输入一堆东西,输入#结束");
		Scanner scanner = new Scanner(System.in);
		// 这个循环不断继续,直到读进来的字符串是"#"才打断
		// 由于Java中(好像不止是在Java,在不少语言都是),字符串是个对象,因此,只能使用equals方法判断
		// ==,!=编译不出错,程序不错,但照样跑,因为对象与对象的==的意思是判断这两个是否都是String对象,不是这样的!
		while (true) {
			String temp = scanner.nextLine();
			// 如果字符串不是什么都没有,不是#
			if (!temp.equals("") && !temp.equals("#")) {
				// 那么就把它压进动态数组
				inputStringArr.add(temp);
			}
			// 如果是#则打断循环
			if (temp.equals("#")) {
				break;
			}
		}
		System.out.println("刚才,你输入的东西为" + inputStringArr);
		// 如果动态数组存在第二个函数,则把它取出并打印出来
		if (inputStringArr.size() > 1) {
			System.out.println("你输入的第二行为:" + inputStringArr.get(1));
		}
	}

	public static void fileInputOutput() throws IOException {
		// 说明我要扫描c:\a.txt,在字符串的\必须转义成\		Scanner scanner = new Scanner(new File("c:\\a.txt"));
		StringBuilder filetoStringTemp = new StringBuilder("");
		// 如果还有下一行的话?hasNext()方法不会导致扫描器Scanner的游标向下跳,因此可以作为判断条件
		// 如果会向下跳就会出现隔行没有被读取的现象
		while (scanner.hasNext()) {
			// StringBuilder没有重载运算符+=号,只能通过append()方法操作,同样的结果
			filetoStringTemp.append(scanner.next());
			// 每读完一行,再补上一个换行,scanner不会把换行读进来
			filetoStringTemp.append("\n");
		}
		// 把StringBuilder转换成String,同样也可以通过其toString实现。
		String filetoString = new String(filetoStringTemp);
		System.out.println(filetoString);
		// 把所有回车换成空格,注意的是replaceAll是返回一个String,必须用来替换原来的字符串,
		// 它不是一个void()方法,弄完就完事了
		filetoString = filetoString.replaceAll("\n", " ");
		System.out.println(filetoString);
		// 判断这个字符串是否以"# "可以看到运行结果返回true,这方法在判断后缀名的时候很有用
		System.out.println(filetoString.endsWith("# "));
		// 用打印流打印到文件,这里指定文件用文件写者来指定,这样就不会出现覆盖输出的问题了
		PrintWriter printwriter = new PrintWriter(new FileWriter("c:\\b.txt",
				true));
		// 跟System.out.println()控制台输出方法有异曲同工之妙,只是我是输出到文件而已
		// 把下面这行代码倒过来看你就能理解
		printwriter.println(filetoString);
		// 必须关闭文件打印流才能完成一次输出,否则,打印的内容永远只在内存!
		printwriter.close();
		System.out.println("已经把字符串filetoString输出到c盘的b.txt里面了。");
	}

	public static void main(String[] args) throws IOException {
		inputOneLine();
		inputMultiLine();
		fileInputOutput();
	}
}
时间: 2024-11-01 23:02:38

【Java】输入与输出与JDK1.5之后的新型字符串StringBuilder的相关文章

java 输入和输出 代码示例

此处省略介绍, package org.rui.io.inout; import java.io.BufferedReader; import java.io.FileReader; /** * 缓冲输入文件 * @author lenovo * */ public class BufferedInputFile { public static String read(String filename) throws Exception { BufferedReader br=new Buffer

Java输入及输出处理(I/O流)

IO流的分类: 按流向分类:输入流.输出流按操作对象分类: 字节流.字符流按功能分类: 节点流.处理流 Input 输入Output 输出Java.io.File类,文件输入输出类 字节流和字符流: 1,字节流InputStream(读),OutputStream(写).2,字符流:Reader(读),Writer(写).基本的读写操作方式:因为数据通常都以文件形式存在.所以就要找到 IO 体系中可以用于操作文件的流对象.通过名称可以更容易获取该对象.因为 IO 体系中的子类名后缀绝大部分是父类

java输入,输出的字符编码问题

我们读取文本(无论从那儿读,键盘,硬盘)的时候: 尽量使用: (从硬盘读)InputStreamReader ir=new           InputStreamReader(fileInputStream,"编码"): (从键盘读)InputStreamReader ir=new InputStreamReader(System.in,"编码"): 可以指定编码. 输出文本时, (输出到硬盘)PrintStream ps=new PrintStream(fil

1.java.io包中定义了多个流类型来实现输入和输出功能,

1.java.io包中定义了多个流类型来实现输入和输出功能,可以从不同的角度对其进行分 类,按功能分为:(C),如果为读取的内容进行处理后再输出,需要使用下列哪种流?(G)   A.输入流和输出流 B.字节流和字符流 C.节点流和处理流   D.File stream E.Pipe stream F.Random stream G.Filter stream

JAVA问题总结13-从键盘输入并输出

JAVA问题总结13-从键盘输入并输出,加从键盘输入三个数,输出并按从大到小排序. package java2; /** * 这是一个从键盘输入并输出的一个test * @author xubo601450868 * @time 2015.8.26 * @version v1.0 * */ import java.util.Scanner; public class test4 { public static void main(String[] args){ Scanner s=new Sca

Java 调用有输入和输出的存储过程

--有输入和输出的存储过程 SQL> create or replace procedure sp_pro8( spNo in varchar2, spName out varchar2) is begin select sname into spName from student where sid= spNo; end; 1 package oracle; 2 3 import java.sql.CallableStatement; 4 import java.sql.Connection;

java 线程 生产者-消费者与队列,任务间使用管道进行输入、输出 讲解示例 --thinking java4

package org.rui.thread.block2; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedB

Java如何处理输入和输出

在Java中为了进行I/O操作,需要用适当的I/O类创建对象,这些对象包含从文件中读数据的方法和向文件中写数据的方法. 例如:要将文本写入temp.txt的文件, 1 PrintWriter pw = new PrintWriter("temp.txt"); 2 pw.print("Hello Java!"); 3 pw.close(); 4 5 Scanner input = new Scanner(new File("temp.txt"));

Java学习笔记—第十章 数据输入与输出

第十章  数据输入与输出 输入流与输出流: (1)输入流:以程序为基准,向程序中输入数据的流定义为输入流.从输入流向程序中输入数据称为读数据(read). (2)输出流:以程序为基准,从程序输出数据的流称为输出流.从程序中将数据输出到输出流称为写数据(write). 字节流和字符流 (1)字节流:按照字节的形式读/写数据.Java中抽象类InputStream和OutputStream及其派生子类用来处理字节流的输入和输出. (2)字符流:按照字符的形式读/写数据.Java中抽象类Reader和