[Java基础教程]第十二章-Java输入输出流
虽然计算机的历史才六七十年,但是研究机器计算的历史非常久远,历史上很多杰出的数学家使用10进制进行了大量的研究,20世纪人类使用电位表示2进制(0,1),计算机才有了飞速的发展。计算机的存储和网络传输都是2进制,每个位为一个bit,每8bit为一个字节。后来计算机的用途逐渐从纯粹的数学计算扩展到各个方面,为了表示文字使用固定2进制串表示各种字符集,这种方式叫编码。目前存在的编码方式各种各样,其中我们会用到的包括ASCII主要表示英文相关字母和符号,GBK编码双字节表示中文常用字符集,UTF-8使用1-3个字节常用中文字符集。如果不涉及与GBK字符集编码的应用交互,最好使用UTF-8字符集进行开发。
日常开发中经常会有访问文件的场景,Java为这种场景提供了几个工具类。
public static void main(String[] args) throws IOException {
File fileTest = new File("test.txt");// 这里不是真的创建一个文件
System.out.println("文件是否存在:" + fileTest.exists());
if (!fileTest.exists()) {
fileTest.createNewFile();// 这里才是创建文件
}
System.out.println("第二次检查文件是否存在:" + fileTest.exists());
System.out.println("文件路径:" + fileTest.getAbsolutePath());
}上面的代码的功能是:获取一个文件句柄,如果文件不存在则创建文件,打印文件的绝对路径。运行上面的代码后刷新一下工程文件,看是否创建一个了个”test.txt”的文件。
File文件类,描述文件(无论是否存在)的信息,exists检查文件是否存在,createNewFile创建文件,getAbsolutePath获取文件绝对路径。有绝对路径就有相对路径,这里的相对路径是指相对于运行时的跟路径,“File fileTest = new File(“test.txt”);”就是使用的相对路径,根据打印的结果我们可以看出来工程运行的根路径为”D:itemslearntest”(不同的机器路径不一样),就是工程的根路径。
根据后缀名(.txt)可以看出,我们创建的是一个文本文件,老规矩向文件中输入“Hello World,你好中国”。
FileOutputStream fos = new FileOutputStream(fileTest);// 文件输出字节流
OutputStreamWriter osw = new OutputStreamWriter(fos);// 字节流向字符流转换 默认为UTF-8编码方式
BufferedWriter bw = new BufferedWriter(osw);// 缓存字符输出流
bw.write("Hello World,你好中国");
bw.flush(); // 刷新缓存,防止未写入文件
bw.close(); // 流关闭
osw.close(); // 流关闭
fos.close(); // 流关闭
System.out.println("写入完毕");Java的文件访问方式经常被吐槽,使用太复杂,各种流类型不断转换 ,如下图所示:
通常文件(文本文件)的访问需要至少3个流,因为文件的存储和传输都是2进制数字,所以先获取字节流OutputStream/InputStream,然后把字节流使用相应的编码方式转换成字符流Writer/Reader,字符流只能单字符传输效率太低,所以又引入一个缓冲字符流BufferedWriter/BufferedReader,缓冲区满了才做输入或者输出操作。BufferedWriter.write(String)作用是把参数的字符串输入到文件中,如果需要换行字符串中添加”n”就可以。如果入参数据太少可能会导致缓冲区没有写满,如果我们不调用flush,可能数据没有真正的写入文件,所以使用BufferedWriter写入后一定要flush。最后记得关闭流,否则可能导致内存丢失。当我们运行多次后,发现文件中仍然就一句”Hello World,你好中国”,内容覆盖了,所以如果需要在文件尾部添加需要使用BufferedWriter.append(String),并且FileOutputStream初始化时设置是否追加为true。
FileInputStream pis = new FileInputStream(fileTest, true);
InputStreamReader isr = new InputStreamReader(pis);
BufferedReader br = new BufferedReader(isr);
String line = br.readLine();// 先读取一行
while (line != null) { // 如果不为空继续读取直到为Null
System.out.println(line);
line = br.readLine();
}
br.close();
isr.close();
pis.close();读取文件时,因为无法确定文件的有多少数据,所以要循环读取直到没有数据返回。
除了文件中读取数据,通过网络也可以读取或者写入数据,同样是使用输入输出流交互,下面我们做一个简单的服务器和客户端的交互测试。
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("监听IP:" + serverSocket.getInetAddress().getLocalHost().getHostAddress() + "; 监听端口:"
+ serverSocket.getLocalPort());
Socket acceptSocket = serverSocket.accept();
InputStream inputStream = acceptSocket.getInputStream();
InputStreamReader isr = new InputStreamReader(inputStream, "utf-8");
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
System.out.println("客户输入:" + line);
}
br.close();
isr.close();
serverSocket.close();
System.out.println("输出结束");
}启动后使用telnet客户端可以连接并交互:
启动链接telnet 192.168.0.6 8080,注意ip和端口换成自己的
交互结果,分别输入了”hello”和”bye”
public static void main(String[] args) throws UnknownHostException,
IOException {
Socket socket = new Socket("127.0.0.1", 8080);
OutputStream outputStream = socket.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
outputStream));
writer.write("hin");
writer.flush();
writer.write("my name is lilein");
writer.flush();
writer.write("byen");
writer.flush();
writer.close();
outputStream.close();
socket.close();
}通过网络的数据交互使用的也是输入流和输出流,多了ServerSocket,Socket用于描述网络连接。网络就是IP:Port进行连接的。
小练习:
读取练习工程中所有的java文件,并统计字母a-z出现的次数(不区分大小写)。
课程中使用的代码:
package com.sunhaojie.learntest.twelfth;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
/**
* @ClassName FileTest
* @Description 文件测试类
*
* @author sunhaojie 3113751575@qq.com
* @date 2016年2月12日 下午9:14:24
*/
public class FileTest {
/**
* @Title main
* @Description 测试File类
* @param args
* @return void
*
* @author sunhaojie 3113751575@qq.com
* @throws IOException
* @date 2016年2月12日 下午9:14:25
*/
public static void main(String[] args) throws IOException {
File fileTest = new File("test.txt");// 这里不是真的创建一个文件
System.out.println("文件是否存在:" + fileTest.exists());
if (!fileTest.exists()) {
fileTest.createNewFile();// 这里才是创建文件
}
System.out.println("第二次检查文件是否存在:" + fileTest.exists());
System.out.println("文件路径:" + fileTest.getAbsolutePath());
FileOutputStream fos = new FileOutputStream(fileTest, true);// 文件输出字节流
OutputStreamWriter osw = new OutputStreamWriter(fos);// 字节流向字符流转换 默认为UTF-8编码方式
BufferedWriter bw = new BufferedWriter(osw);// 缓存字符输出流
bw.write("Hello World,你好中国n");
bw.append("Hello World,你好中国n");
bw.flush(); // 刷新缓存,防止未写入文件
bw.close(); // 流关闭
osw.close(); // 流关闭
fos.close(); // 流关闭
System.out.println("写入完毕");
FileInputStream pis = new FileInputStream(fileTest);
InputStreamReader isr = new InputStreamReader(pis);
BufferedReader br = new BufferedReader(isr);
String line = br.readLine();// 先读取一行
while (line != null) { // 如果不为空继续读取直到为Null
System.out.println(line);
line = br.readLine();
}
br.close();
isr.close();
pis.close();
}
}
package com.sunhaojie.learntest.twelfth;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
/**
*
* @ClassName SocketServerTest
* @Description 服务器端测试类
*
* @author sunhaojie 3113751575@qq.com
* @date 2016年2月12日 下午10:53:45
*/
public class SocketServerTest {
@SuppressWarnings("static-access")
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("监听IP:" + serverSocket.getInetAddress().getLocalHost().getHostAddress() + "; 监听端口:"
+ serverSocket.getLocalPort());
Socket acceptSocket = serverSocket.accept();
InputStream inputStream = acceptSocket.getInputStream();
InputStreamReader isr = new InputStreamReader(inputStream, "utf-8");
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
System.out.println("客户输入:" + line);
}
br.close();
isr.close();
serverSocket.close();
System.out.println("输出结束");
}
}
package com.sunhaojie.learntest.twelfth;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
/**
*
* @ClassName SocketClientTest
* @Description 测试端输出类
*
* @author sunhaojie 3113751575@qq.com
* @date 2016年2月12日 下午10:54:03
*/
public class SocketClientTest {
public static void main(String[] args) throws UnknownHostException,
IOException {
Socket socket = new Socket("127.0.0.1", 8080);
OutputStream outputStream = socket.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
outputStream));
writer.write("hin");
writer.flush();
writer.write("my name is lilein");
writer.flush();
writer.write("byen");
writer.flush();
writer.close();
outputStream.close();
socket.close();
}
}
建议继续学习:
- [Java基础教程]第十一章-Java类和对象 (阅读:3077)
- [Java基础教程]第十三章-Java多线程 (阅读:3027)
- 避免输入 (阅读:2966)
- 触摸屏输入的交互设计 (阅读:2955)
- PHP里模拟$_PUT (阅读:2442)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:sunhaojie 来源: 孙豪杰的博客
- 标签: Java基础教程 输入 输出
- 发布时间:2016-03-15 23:35:34
-
[938] WordPress插件开发 -- 在插件使用 -
[119] 解决 nginx 反向代理网页首尾出现神秘字 -
[51] 如何保证一个程序在单台服务器上只有唯一实例( -
[50] ps 命令常见用法 -
[49] 用 Jquery 模拟 select -
[49] 整理了一份招PHP高级工程师的面试题 -
[49] 海量小文件存储 -
[48] find命令的一点注意事项 -
[48] Innodb分表太多或者表分区太多,会导致内 -
[47] 全站换域名时利用nginx和javascri



