代码演示需要提前在项目根目录下创建一个 file.txt ,并在其中输入一些信息
不习惯这样看代码的话,我把代码上传到了 github 上:https://github.com/Mr1wangjiabin/java-io
unicode
编码byte byte byte ...
的数据序列byte
的存储结果public class EncodeDemo {
public static void main(String[] args) throws Exception {
/**
* 文本文件,可以是任意编码的字节序列
* 如果我们在中文机器上直接创建文本文件,那么该文件只认识ANSI编码
*
* 字节序列只能进行同种编码间的传输,如果编码方式不一致,会出现乱码
*/
//UTF-8 输出e6 b5 8b e8 af 95 41 42 43
//一个汉字 3 个字节,字母 1 个字节
String s = "测试ABC";
byte[] bytes1 = s.getBytes();//转换成字节是项目默认的编码 UTF-8
System.out.println("UTF-8编码:");
for (byte b : bytes1) {
System.out.print(Integer.toHexString(b & 0xff) + " ");//将字节转换为 16进制 int型输出
}
System.out.println();
//GBK输出b2 e2 ca d4 41 42 43
//一个汉字 2 个字节,字母 1 个字节
System.out.println("GBK编码:");
byte[] bytes2 = s.getBytes("gbk");
for (byte b : bytes2) {
System.out.print(Integer.toHexString(b & 0xff) + " ");
}
System.out.println();
//UTF-16be 输出6d 4b 8b d5 0 41 0 42 0 43
//一个汉字 2 个字节,字母 2 个字节
System.out.println("UTF-16be编码:");
byte[] bytes3 = s.getBytes("utf-16be");
for (byte b : bytes3) {
System.out.print(Integer.toHexString(b & 0xff) + " ");
}
//关闭流
raf.close
}
}
java.io.file
用来表示文件或者目录File
类用于表示文件(目录)的信息(名称、大小等)。不能用于文件内容的访问/**
* File 的构造函数:
* File(filepath) filepath为文件全目录
* File(filepath,filepath1,filepath2...) filepath1为filepath的子目录
* File.separator 文件分隔符
* exists 验证file是否存在
* mkdir 创建一个文件夹/目录
* mkdir 创建多级目录
* delete 删除文件
* isDirectory 判断file 是否是文件夹
* isFile 判断file 是否是文件
* getAbsolutePath 获取全路径
* getName 获取文件名称
* createNewFile 创建一个新文件
*/
public class FileDemo {
public static void main(String[] args) throws IOException {
File file = new File("E:\\Project\\io\\test");
File file1 = new File("E:" + File.separator
+ "Project" + File.separator
+ "io"+ File.separator
+ "test.text");
if(!file.exists()){
file.mkdir();
}else {
file.delete();
}
System.out.println(file.isDirectory());//判断file 是否是文件夹
System.out.println(file.isFile());//判断file 是否是文件
System.out.println(file.getAbsolutePath());//获取全路径
System.out.println(file.getName());//获取文件名称
if (!file1.exists()){
file1.createNewFile();
}else {
file1.delete();
}
}
}
import java.io.File;
/**
* list 返回目录/文件下的所有文件名
* listFiles 返回文件下的所有文件
*
* 练习,完成目录下所有子目录的查询
*/
public class FileUtils {
public static void main(String[] args) throws IllegalAccessException {
File file = new File("E:/Project/io");
FileUtils.listFile(file);
}
public static void listFile(File file) throws IllegalAccessException {
//首先判断文件是否存在以及文件是文件夹
if(!file.exists()){
throw new IllegalAccessException(file + " 不存在");
}
if (!file.isDirectory()){
throw new IllegalAccessException(file + " 不是一个文件夹");
}
File[] files = file.listFiles();
if (files.length > 0 && files != null){
for (File file1 : files) {
if (file1.isDirectory()){
FileUtils.listFile(file1);
}else {
System.out.println(file);
}
}
}
}
}
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Arrays;
/**
** java 文件模型
* 在硬盘上是 byte byte 存储的,是数据的集合
* 打开文件
* 有两种模式:"rw"(读写) "r"(只读)
* RandomAccessFile raf = new RandomAccessFile("rw")
* 文件指针,打开文件时,文件指针在开头 pointer = 0
* 写方法
* raf.writer() -->只写一个字节(后8位)同时指针指向下一个位置,准备再次写入
* 读方法
* int b = raf.read() --> 读一个字节
* 文件读写完成一定要关闭
*
* 其他API
* getFilePointer 获取指针当前所在位置
*
*
*/
public class RandomAccessFileDmo {
public static void main(String[] args) throws IOException {
//创建文件
File file = new File("demo");
if(!file.exists()){
file.mkdir();
}
File file1 = new File(file, "raf.dat");
if(!file1.exists()){
file1.createNewFile();
}
//对文件的读写操作
RandomAccessFile raf = new RandomAccessFile(file1, "rw");
System.out.println("指针当前所在位置为:" + raf.getFilePointer());//获取指针当前所在位置
//写入一个字节
//默认编码UTF-8,一个汉字 3 个字节,一个字母 1 个字节
raf.write('A');
System.out.println("指针当前所在位置为:" + raf.getFilePointer());//获取指针当前所在位置
int i = 0x7fffffff;
//用write方法每次只能写一个字节,如果要把i写进去就得写4次
raf.write((i >>> 24) & 0xff);//右移 24 位,并清空其余的0值
raf.write((i >>> 16) & 0xff);
raf.write((i >>> 8) & 0xff);
raf.write((i) & 0xff);
System.out.println("指针当前所在位置为:" + raf.getFilePointer());//获取指针当前所在位置
//可以直接写一个 int 型变量,底层实现和上面的方法一样
raf.writeInt(i);
//写一个汉字
String s = "中";
byte[] bytes = s.getBytes();
raf.write(bytes);
System.out.println("指针当前所在位置为:" + raf.getFilePointer());//获取指针当前所在位置
//读文件,必须把指针移动到头部
raf.seek(0);
//把文件中的内容都读取到字节数组中
byte[] bytes1 = new byte[(int) raf.length()];
raf.read(bytes1);
System.out.println(Arrays.toString(bytes1));//将数组输出
//将字节数组转换为字符串输出
String s1 = new String(bytes1);
System.out.println(s1);
}
}
package byteStream;
import java.io.FileInputStream;
import java.io.IOException;
/**
* 读取指定文件内容,按照16进制输出到控制台。并且每输出10个byte换行
* 批量读取
*/
public class FileInputStreamTest {
public static void main(String[] args) throws IOException {
printHex("file.txt");
}
public static void printHex(String filename) throws IOException{
FileInputStream fis = new FileInputStream(filename);
byte[] bytes = new byte[8 * 1024];
int b = 0;
int j = 1;
while ((b = fis.read(bytes,0,bytes.length)) != -1){
for (int i = 0; i < b; i++) {
System.out.print(Integer.toHexString(bytes[i] & 0xff) + " ");
if(((j++)%10)==0){
System.out.println();
}
}
}
fis.close();
}
}
package byteStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 从文件中读取数据
*/
public class FileOutPutStreamTest {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("out.dat");
byte[] bytes = "你好".getBytes();
fos.write(bytes);
fos.close();
FileInputStreamTest.printHex("out.dat");
}
}
package byteStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
* 完成文件的复制
*/
public class FileCopyTest {
public static void main(String[] args) throws Exception {
fileCopy(new File("file.txt"),new File("fileout.txt"));
}
/**
* 文件复制
* 问什么传入参数不用文件名?
* 需要判断源文件是否存在
* @param srcFile
* @param destFile
*/
public static void fileCopy(File srcFile,File destFile) throws Exception{
if(!srcFile.exists()){
throw new IllegalAccessException("文件" + srcFile + "不存在");
}
if(!srcFile.isFile()){
throw new IllegalAccessException("文件" + srcFile + "不是文件");
}
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
byte[] bytes = new byte[8 * 1024];
int b = 0;
if((b = fis.read(bytes,0,bytes.length)) != -1){
fos.write(bytes,0,b);
fos.flush();
}
fis.close();
fos.close();
}
}
package byteStream;
import java.io.*;
public class BufferedTest {
public static void main(String[] args) throws Exception{
copyFile(new File("E:\\Project\\io\\src\\main\\java\\file\\FileDemo.java"),
new File("fileOut2.txt"));
}
public static void copyFile(File srcFile, File destFile) throws Exception{
if(!srcFile.exists()){
throw new IllegalAccessException("文件" + srcFile + "不存在");
}
if(!srcFile.isFile()){
throw new IllegalAccessException("文件" + srcFile + "不是文件");
}
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
int c;
while ((c = bis.read())!= -1){
bos.write(c);
bos.flush();
}
bis.close();
bos.close();
}
}
InputStreamReader
按照编码将 byte
流解析为 char
流OutputStreamWriter
默认项目的编码,操作的时候要写文件本身的编码package charStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
/**
* InputStreamReader && OutputStreamWriter 实现文件复制
*/
public class FileCopyTest {
public static void main(String[] args) throws Exception{
InputStreamReader isr = new InputStreamReader(new FileInputStream("file.txt"));
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("fileOut3.txt"));
char[] chars = new char[8 * 1024];
int c;
while ((c = isr.read(chars,0,chars.length)) != -1){
osw.write(chars,0,c);
osw.flush();
}
isr.close();
osw.close();
}
}
package charStream;
import java.io.FileReader;
import java.io.FileWriter;
/**
* InputStreamReader && OutputStreamWriter 实现文件复制
*/
public class FileCopyByFileTest {
public static void main(String[] args) throws Exception{
FileReader fr = new FileReader("file.txt");
FileWriter fw = new FileWriter("fileOut4.txt");
char[] chars = new char[8 * 1024];
int d;
while ((d = fr.read(chars,0,chars.length)) != -1){
fw.write(chars,0,d);
}
fr.close();
fw.close();
}
}
PrintWriter
用起来比 BufferedWriter
方便不少,因此我不再写 BufferedWriter
相关代码,感兴趣的自己查吧package charStream;
import java.io.*;
public class FileCopyByBuffer {
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("file.txt")));
PrintWriter pw = new PrintWriter(
new FileOutputStream("fileOut5.txt"),true);//在文件参数为 OutputStream时,可以设置自动清空缓存
String line;
while ((line = br.readLine()) != null){
pw.println(line);
}
br.close();
pw.close();
}
}
byte
存储称为序列化,反之为反序列化ObjectOutputStream
方法 writeObject
ObjectInputStream
方法 readObject
Serializable
接口的类才能序列化transient
修饰的变量不会被 JVM 自动序列化,但可以手动,用以提高性能(这部分不懂,就简单的提一下)package SerializableTest;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class SerializableTest {
public static void main(String[] args) throws Exception{
//对象序列化
ObjectSerializable();
//对象反序列化
ObjectInSerializable();
}
/**
* 对象序列化
* @throws Exception
*/
public static void ObjectSerializable() throws Exception{
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.dat"));
Student student = new Student(1L, "小王");
oos.writeObject(student);
oos.flush();
oos.close();
}
public static void ObjectInSerializable() throws Exception{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.dat"));
Student student = (Student) ois.readObject();
System.out.println(student);
ois.close();
}
}