程序员面试宝典——第六章 传递和引用(写入文件、FileWriter、FileOutputStream、BufferedReader、InputStream、InputStreamReader)
1 静态变量与实例变量
在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加。
在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来引用。
在任意多个类的实例中,一个静态变量的实例只存在一个。
例如:对于下面的程序,无论创建多少个实例对象,永远都只分配了一个staticVar变量,并且每创建一个实例对象,这个staticVar就会加1;但是,每创建一个实例对象,就会分配一个instanceVar,即可能分配多个instanceVar,并且每个instanceVar的值都只自加了1次。
public class Test11 {
public static int staticVar = 0;
public int instanceVar = 0;
public Test11() {
staticVar++;
instanceVar++;
System.out.println("staticVar=" + staticVar + ",instanceVar="
+ instanceVar);
}
public static void main(String[] args) {
Test11 test = new Test11();
Test11 test1 = new Test11();
Test11 test2 = new Test11();
}
}
//输出:
//staticVar=1,instanceVar=1
//staticVar=2,instanceVar=1
//staticVar=3,instanceVar=1
2 字符串写入文件操作
注意:如何实现数据的换行?
\n可以实现换行,但是windows系统自带的记事本打开并没有换行,这是为什么呢?因为windows识别的换行不是\n,而是\r\n。
windows:\r\n
linux:\n
mac:\r
1) 利用FileWriter
:FileWriter
类从OutputStreamWriter
类继承而来。该类按字符向流中写入数据。
package com.test;
import java.io.FileWriter;
import java.io.IOException;
public class TestFileWriter{
public static void main(String[] args){
String str = "hello world!";
FileWriter writer;
try{
writer = new FileWriter("D:/Users/yxx/eclipseworkspace/token1.txt");
writer.write(str);//写入
writer.flush();//清空
writer.close();//关闭
}catch (IOException ioe){
ioe.printStackTrace();
}
}
}
2) 利用FileWrite
追加文件内容:
package com.test;
import java.io.FileWriter;
import java.io.IOException;
public class TestFileWriter{
public static void main(String[] args){
String str = "hello world1!\r\n";
FileWriter writer;
try{
//writer = new FileWriter("D:/Users/yxx/eclipseworkspace/token1.txt");
writer = new FileWriter("D:/Users/yxx/eclipseworkspace/token1.txt",true);
writer.write(str);
writer.flush();
writer.close();
}catch (IOException ioe){
ioe.printStackTrace();
}
}
}
3) 利用FileOutputStream
:FileOutputStream的write() 方法只接受byte[] 类型的参数,所以需要将string通过getBytes()方法转换为字节数组。
1、首先判断文件是否存在,不存在就新建一个
2、写入文件是以覆盖方式
3、文件不存在会自动创建,存在则会被重写
package com.test;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class testFileUotputStream {
public static void main(String[] args) throws IOException {
String str="hello,world2.";//要写入的字符串
File txt = new File("D:/Users/yxx/eclipseworkspace/token2.txt");
if(!txt.exists()){//第一步,检查文件是否存在
txt.createNewFile();//若不存在,则新建一个文件
}
byte[] bytes=new byte[512];//创建字符数组
bytes=str.getBytes();//将字符串转换为字节数组
int b=bytes.length;//字节长度
FileOutputStream fos=new FileOutputStream(txt);
fos.write(bytes, 0, b);//写入
fos.write(bytes);//写入
fos.flush();//清空
fos.close();//关闭
}
}
4) 利用FileOutputStream的追加功能
package com.test;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class testFileUotputStream2 {
public static void main(String[] args) throws IOException {
String str="hello,world2. ";//要写入的字符串
File txt = new File("D:/Users/yxx/eclipseworkspace/token2.txt");
if(!txt.exists()){//第一步,检查文件是否存在
txt.createNewFile();//若不存在,则新建一个文件
}
byte[] bytes=new byte[512];//创建字符数组
bytes=str.getBytes();//将字符串转换为字节数组
int b=bytes.length;//字节长度
//FileOutputStream fos=new FileOutputStream(txt);
FileOutputStream fos=new FileOutputStream(txt,true);//true表示在文件末尾追加
fos.write(bytes, 0, b);//写入
fos.write(bytes);//写入
fos.flush();//清空
fos.close();//关闭
}
}
3 BufferedReader
1、java.io.BufferedReader和java.io.BufferedWriter类各拥有8192字符的缓冲区。当BufferedReader在读取文本文件时,会先尽量从文件中读入字符数据并置入缓冲区,而之后若使用read()方法,会先从缓冲区中进行读取。如果缓冲区数据不足,才会再从文件中读取,使用BufferedWriter时,写入的数据并不会先输出到目的地,而是先存储至缓冲区中。如果缓冲区中的数据满了,才会一次对目的地进行写出。
2、从标准输入流System.in中直接读取使用者输入时,使用者每输入一个字符,System.in就读取一个字符。为了能一次读取一行使用者的输入,使用了BufferedReader来对使用者输入的字符进行缓冲。readLine()方法会在读取到使用者的换行字符时,再一次将整行字符串传入。
3、System.in是一个位流,为了转换为字符流,可使用InputStreamReader为其进行字符转换,然后再使用BufferedReader为其增加缓冲功能。例如:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
经常用于处理数据流的三个类的区别:
InputStream
: 是所有字节输入流的超类,一般使用它的子类:FileInputStream
等,它能输出字节流;
InputStreamReader
: 是字节流与字符流之间的桥梁,能将字节流输出为字符流,并且能为字节流指定字符集,可输出一个个的字符;
BufferedReader
: 提供通用的缓冲方式文本读取,readLine读取一个文本行, 从字符输入流中读取文本,缓冲各个字符,从而提供字符、数组和行的高效读取。
例题:写一个Java应用程序,从键盘中输入两个参数,然后输出他们的平方值和立方值:
package com.test;
import java.io.*;
class InputData{//输入
static private String s="";
static public void input(){
BufferedReader reader = new BufferedReader(
new InputStreamReader(System.in)
);
try{
s=reader.readLine();
}catch (IOException ioe) {
ioe.printStackTrace();
}
}
static public int getInt(){
input();
return Integer.parseInt(s);//字符串S转换为整型数组后返回
}
}
class Result{//输出
void print(int d){
System.out.println(d+"的平方为 "+ d*d);
System.out.println(d+"的立方为 "+ d*d*d);
}
}
public class PrintResult {//实现
public static void main(String[] args) {
Result result=new Result();
System.out.println("请输入一个整数: ");
int a=InputData.getInt();
result.print(a);
}
}
该例子还可以用之前学到的,利用Scanner从键盘输入数字来实现:
package com.test;
import java.util.Scanner;
public class TestScanner {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner x=new Scanner(System.in);
System.out.println("请输入一个整数: ");
int i=x.nextInt();
System.out.println(i+"的平方为:"+i*i);
System.out.println(i+"的立方为:"+i*i*i);
}
}
学习资料:
IO流
Java中IO流学习总结