Java io流 字符 字节转换流
package io流;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
/**
* 字节字符转换流
* InputStreamReader
* OutputStreamWriter
*
* */
public class 字节字符转换流 {
public static void main(String[] args) {
try {
//指定编码形式的 读取文件
FileInputStream in1 = new FileInputStream("charSet.txt");
InputStreamReader in2 = new InputStreamReader(in1,"utf-8"); //依赖于别的流
char[] arr = new char[100];
in2.read(arr);
System.out.println(new String(arr));
in2.close();
in1.close();
//指定编码形式的存入文件
String name ="Tom你好世界哈哈哈哈";
FileOutputStream out1 = new FileOutputStream("charSet2.txt");
OutputStreamWriter out2 = new OutputStreamWriter(out1,"utf-8");
out2.write(name);
out2.close();
out1.close();
//-----------练习 --------
//功能函数
//1. 给定一个txt文件 copy操作 变成另一指定名称,位置,编码格式的文件
fun1("data.txt", "img","1.txt", "gbk");
//功能函数
//2. 给定一个txt文件 copy操作 变成另一指定名称,位置,编码格式的文件
// 在拷贝的时候不要拷贝原始数据 每个字符做个变换
// 在原始字符的编码值的基础上 异或 n
} catch (Exception e) {
e.printStackTrace();
}
}
//功能函数
//1. 给定一个txt文件 copy操作 变成另一指定名称,位置,编码格式的文件
public static void fun1(String orgFile,
String targetPos,//img/lib/sta.txt
String targetFile,
String charsetName) throws Exception{
File org = new File(orgFile);
File tarDir = new File(targetPos);//目标所在的问价夹
File tarFile = new File(targetPos+"/"+targetFile);//目标文件
if (org.exists()&&org.isFile()) {
//看参数2 目标文件夹
if (!tarDir.exists()) { //若目标文件夹不存在 自动创建
tarDir.mkdirs();
}
//看参数3 目标文件是否已经存
if(tarFile.exists()){
throw new Exception("参数2+参数3 当前目标 已有同名文件");
}
//创建新的文件
tarFile.createNewFile();
FileInputStream in1 = new FileInputStream(org);
InputStreamReader in2 = new InputStreamReader(in1);
FileOutputStream out1 = new FileOutputStream(tarFile);
OutputStreamWriter out2 = new OutputStreamWriter(out1,charsetName);
char[] arr = new char[100]; //101
while (true) {
int tmp = in2.read(arr,0,100);
if (tmp==-1) {
break;
}
//arr加密处理一下
// for (int i = 0; i < tmp; i++) {
// arr[i] = (char) (arr[i] ^ 2);
// }
out2.write(arr, 0, tmp);
}
out2.close();
out1.close();
in2.close();
in1.close();
}else{
throw new Exception("参数1有问题");
}
}
}
补充
package sugar.utils.stream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.RandomAccessFile;
import java.nio.charset.Charset;
//其中,以Stream结尾的为字节流,
//以Writer或者Reader结尾的为字符流。
//所有的输入流都是抽象类IuputStream(字节输入流)
//或者抽象类Reader(字符输入流)的子类,
//所有的输出流都是抽象类OutputStream(字节输出流)
//或者抽象类Writer(字符输出流)的子类。
//字符流能实现的功能字节流都能实现,
//反之不一定。如:图片,视频等二进制文件,只能使用字节流读写。
public class CharStreamUtil {
public static void main(String[] args) throws IOException {
//1
// randomInsert("source/random.txt" , 45 , "插入的内容\r\n");
//2
// randomReadWrite("source/random.txt" , 3 , "AABB\r\n");
//3
// String str = buffReadTextFile("source/random.txt");
// System.out.println(str);
//4
//GBK转UTF-8
encode2enc("source/GBK.txt", "GBK", "source/encodeUTF-8.txt","UTF8");
}
// 测试阶段
public static void readTextFile() {
FileInputStream fis = null;
InputStreamReader inReader = null;
BufferedReader bufReader = null;
BufferedWriter bufWriter = null;
try {
//
// FileInputStream 节点流 直接从文件创建 不依赖与其它的流对象
fis = new FileInputStream("source/test_utf8.txt");
inReader = new InputStreamReader(fis, "UTF8");
// 缓冲字符输入流
bufReader = new BufferedReader(inReader);
//
bufWriter = new BufferedWriter(new FileWriter("source/text_3.txt"));
//
String input = null;
// 每读一行进行一次写入动作
// 当读到文件字符 end停止循环!!!!
while (!(input = bufReader.readLine()).equals("end")) {
bufWriter.write(input);
// 写入
bufWriter.newLine();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
// 关闭流,注意关闭的顺序
bufReader.close();
bufWriter.close();
inReader.close();
fis.close();
} catch (Exception e2) {
// TODO: handle exception
}
}
// ****
// 注意原文件 test_utf8.txt 最后一行必须是end
// 且end不会被写入新文件中
}
/**
* 字符转码
* @param fileName
* @param inEncode "UTF8" "GBK" 等
* @param targetFile
* @param outEncode
*/
public static void encode2enc(String fileName,String inEncode, String targetFile,String targetEncode) {
// Java7 新增 try后面加的括号
// 括号里面是必须显式关闭的物理资源,如数据库连接、网络连接、磁盘文件
// 在try语句结束时自动关闭该资源,不需要finally 判断关闭了
try (
// FileInputStream 节点流 直接从文件创建 不依赖与其它的流对象
FileInputStream fis = new FileInputStream(fileName);
InputStreamReader inReader = new InputStreamReader(fis, inEncode);
// 缓冲字符输入流
BufferedReader bufReader = new BufferedReader(inReader);
//不能转码
// BufferedWriter bufWriter = new BufferedWriter(new FileWriter(targetFile));
FileOutputStream fos = new FileOutputStream(targetFile);
OutputStreamWriter outWriter = new OutputStreamWriter(fos,targetEncode);
BufferedWriter bufWriter = new BufferedWriter(new FileWriter(targetFile));
){
String line = null;
//逐行读取
while ((line = bufReader.readLine()) != null) {
bufWriter.write(line);
// 写入
bufWriter.newLine();
}
} catch (Exception e) {
// TODO: handle exception
}
}
/**
* 读取文本文件
* @param fileName
* @return 文本内容
*/
public static String buffReadTextFile(String fileName) {
// Java7 新增 try后面加的括号
// 括号里面是必须显式关闭的物理资源,如数据库连接、网络连接、磁盘文件
// 在try语句结束时自动关闭该资源,不需要finally 判断关闭了
StringBuilder strBuilder = new StringBuilder();
try ( // 创建输入流对象
BufferedReader br = new BufferedReader(new FileReader(fileName));// 文件不存在会抛出java.io.FileNotFoundException
) {
// 文本文件复制
// char [] chs=new char[1024];
// int len=0;
//
// while((len=br.read(chs))!=-1) {
//返回的是null
// strBuilder.append(br.readLine());
// }
String line = null;
//逐行读取
while ((line = br.readLine()) != null) {
strBuilder.append(line);
}
} catch (Exception e) {
// TODO: handle exception
}
return strBuilder.toString();
}
/**
* 复制一个文本文件到另一个文件
* @param fileName
* @param targetFile
*/
public static void buffCopyTextFile(String fileName, String targetFile) {
// Java7 新增 try后面加的括号
// 括号里面是必须显式关闭的物理资源,如数据库连接、网络连接、磁盘文件
// 在try语句结束时自动关闭该资源,不需要finally 判断关闭了
try ( // 创建输入流对象
BufferedReader br = new BufferedReader(new FileReader(fileName)); // 文件不存在会抛出java.io.FileNotFoundException
// 创建输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter(targetFile));) {
// 文本文件复制
char[] chs = new char[1024];
int len = 0;
while ((len = br.read(chs)) != -1) {
bw.write(chs, 0, len);
}
} catch (Exception e) {
// TODO: handle exception
}
}
/**
* 随机存储在文件最后添加字符串
*
* @param fileName
* @param position
* @param appendContent
*/
public static void randomAppend(String fileName, long position, String appendContent) {
// Java7 新增 try后面加的括号
// 括号里面是必须显式关闭的物理资源,如数据库连接、网络连接、磁盘文件
// 在try语句结束时自动关闭该资源,不需要finally 判断关闭了
try (
// 以读、写方式打开一个RandomAccessFile对象
RandomAccessFile raf = new RandomAccessFile(fileName, "rw")) {
// 将记录指针移动到文件的最后
raf.seek(raf.length());
raf.write(appendContent.getBytes());
} catch (IOException ex) {
ex.printStackTrace();
}
}
/**
* 随机存储写入指定位置
*
* @param fileName
* @param position
* @param insertContent
*/
public static void randomReadWrite(String fileName, long position, String insertContent) {
File tmp = null;
try {
tmp = File.createTempFile("tmp", null);
tmp.deleteOnExit();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// Java7 新增 try后面加的括号
// 括号里面是必须显式关闭的物理资源,如数据库连接、网络连接、磁盘文件
// 在try语句结束时自动关闭该资源,不需要finally 判断关闭了
try (RandomAccessFile raf = new RandomAccessFile(fileName, "rw");
// 使用临时文件来保存插入点后的数据
FileOutputStream tmpOut = new FileOutputStream(tmp);
FileInputStream tmpIn = new FileInputStream(tmp)) {
raf.seek(position);
// ------下面代码将插入点后的内容读入临时文件中保存------
byte[] bbuf = new byte[64];
// 用于保存实际读取的字节数
int hasRead = 0;
// 使用循环方式读取插入点后的数据
while ((hasRead = raf.read(bbuf)) > 0) {
// 将读取的数据写入临时文件
tmpOut.write(bbuf, 0, hasRead);
}
// ----------下面代码插入内容----------
// 把文件记录指针重新定位到position位置
raf.seek(position);
// 追加需要插入的内容
raf.write(insertContent.getBytes());
// 追加临时文件中的内容
while ((hasRead = tmpIn.read(bbuf)) > 0) {
raf.write(bbuf, 0, hasRead);
}
} catch (Exception e) {
}
}
}
package sugar.utils.stream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
public class NIOByteUtil {
public static void main(String[] args) {
// TODO Auto-generated method stub
//1
byte [] byteArr = channelMapByteRead("source/byte.txt", "UTF8");
System.out.println(byteArr);
System.out.println("----------\n");
for (byte b : byteArr) {
System.out.println((char)b);
}
}
public static byte[] channelMapByteRead(String fileName, String targetEncode) {
File f = new File(fileName);
String str = null;
byte[] byteArr = null;
// Java7 新增 try后面加的括号
// 括号里面是必须显式关闭的物理资源,如数据库连接、网络连接、磁盘文件
// 在try语句结束时自动关闭该资源,不需要finally 判断关闭了
try (
// 创建FileInputStream,以该文件输入流创建FileChannel
FileChannel inChannel = new FileInputStream(f).getChannel();
) {
// 将FileChannel里的全部数据映射成ByteBuffer
MappedByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, f.length());
for (int i = 0; i < buffer.capacity(); i++) {
System.out.println(buffer.get(i));
}
} catch (IOException ex) {
ex.printStackTrace();
}finally {
}
return byteArr;
}
}
package sugar.utils.stream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
/**
* Channel:通道 position(后面简写为p):指针位置,当使用Buffer从Channel中读取数据时,position刚好到已经读到多少的数据
* 刚创建一个Buffer,p为0,如果从Channel中读取2个数据,p为2,指向第3个位置。 limit:界限,位于limit后的数据不可读写。
* capacity:容量,不能为负值,创建容量不可更改。
*
* //创建一个FileChannel File f = new File("a.txt"); //
* 创建FileInputStream,以该文件输入流创建FileChannel FileChannel channel = new
* FileInputStream(f).getChannel(); //将FileChannel位置移到0 channel.position(0);
*
* Buffer:缓冲 ByteBuffer:Buffer常用的子类,可以在底层字节数组进行get/set操作
*
* // 定义一个ByteBuffer对象,用于重复取水
* ByteBuffer bbuff = ByteBuffer.allocate(256); //
* 创建Charset对象 Charset charset = Charset.forName(targetEncode); //
* 创建解码器(CharsetDecoder)对象 CharsetDecoder decoder = charset.newDecoder(); //
* //编码器 // CharsetEncoder encoder = charset.newEncoder();
*
* // 将ByteBuffer的内容转码 CharBuffer cbuff = decoder.decode(bbuff);
*/
public class NIOCharUtil {
public static void main(String[] args) {
// TODO Auto-generated method stub
// System.out.println(System.getProperties());
// 1
// channelCopyFile("source/text_5.txt","source/channel.txt","UTF8");
// 2
// String str = channelNotLargeRead("source/channel.txt", "UTF8");
// System.out.println(str);
// 3
// channelWrite("1232 ABC ddd \"双引号内容 \" \n/%¥#*&!@# 呵呵哒", "source/channelWrite.txt", "GBK");
//4
// channelAppend("\nappend内容", "source/channelWrite.txt", "GBK");
//5
channelMapRead("source/channel.txt", "UTF8");
}
/**
* 使用map()方法一次将所有文件内容 映射到内存中
*
* 复制文件 指定编码输出
*
* @param fileName
* @param targetFile
* @param targetEncode
*/
public static void channelCopyFile(String fileName, String targetFile, String targetEncode) {
File f = new File(fileName);
// Java7 新增 try后面加的括号
// 括号里面是必须显式关闭的物理资源,如数据库连接、网络连接、磁盘文件
// 在try语句结束时自动关闭该资源,不需要finally 判断关闭了
try (
// 创建FileInputStream,以该文件输入流创建FileChannel
FileChannel inChannel = new FileInputStream(f).getChannel();
// 以文件输出流创建FileBuffer,用以控制输出
FileChannel outChannel = new FileOutputStream(targetFile).getChannel()) {
// 将FileChannel里的全部数据映射成ByteBuffer
MappedByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, f.length()); // ①
// 使用GBK的字符集来创建解码器
Charset charset = Charset.forName(targetEncode);
// 直接将buffer里的数据全部输出
outChannel.write(buffer); // ②
// 再次调用buffer的clear()方法,复原limit、position的位置
buffer.clear();
// 创建解码器(CharsetDecoder)对象
CharsetDecoder decoder = charset.newDecoder();
// 使用解码器将ByteBuffer转换成CharBuffer
CharBuffer charBuffer = decoder.decode(buffer);
// CharBuffer的toString方法可以获取对应的字符串
// System.out.println(charBuffer);
} catch (IOException ex) {
ex.printStackTrace();
}
}
/**
* 使用map()方法一次将所有文件内容 映射到内存中
*
* 读取指定文件内容
* @param fileName
* @param targetEncode
* @return
*/
public static String channelMapRead(String fileName, String targetEncode) {
File f = new File(fileName);
String str = null;
// Java7 新增 try后面加的括号
// 括号里面是必须显式关闭的物理资源,如数据库连接、网络连接、磁盘文件
// 在try语句结束时自动关闭该资源,不需要finally 判断关闭了
try (
// 创建FileInputStream,以该文件输入流创建FileChannel
FileChannel inChannel = new FileInputStream(f).getChannel();
) {
// 将FileChannel里的全部数据映射成ByteBuffer
MappedByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, f.length()); // ①
// 使用GBK的字符集来创建解码器
Charset charset = Charset.forName(targetEncode);
// 再次调用buffer的clear()方法,复原limit、position的位置
buffer.clear();
// 创建解码器(CharsetDecoder)对象
CharsetDecoder decoder = charset.newDecoder();
// 使用解码器将ByteBuffer转换成CharBuffer
CharBuffer charBuffer = decoder.decode(buffer);
// CharBuffer的toString方法可以获取对应的字符串
System.out.println(charBuffer.toString());
str = charBuffer.toString();
} catch (IOException ex) {
ex.printStackTrace();
}finally {
}
return str;
}
/**
* 不推荐超大文本读取,因为
* //FileChannel的大小 long强制为int !!!
* //int size = (int) fis.getChannel().size();
* int size = (int) f.length();
* 担心Channel对于文件太大,使用map()方法一次将所有文件内容 映射到内存中引起性能下降
*
*
* 获取文本内容 指定编码输出
*
* @param fileName
* @param targetEncode
* @return
*/
public static String channelNotLargeRead(String fileName, String targetEncode) {
// String str = null;
StringBuilder sBuilder = new StringBuilder();
// 不使用java7的try()处理方法
FileInputStream fis = null;
FileChannel fChannel = null;
File f = new File(fileName);
try {
// 创建文件输入流
fis = new FileInputStream(f);
// 创建一个FileChannel
fChannel = fis.getChannel();
//FileChannel的大小 long强制为int !!!
// int size = (int) fis.getChannel().size();
int size = (int) f.length();
// 定义一个ByteBuffer对象,用于重复取水
ByteBuffer bbuff = ByteBuffer.allocate(size);
// 将FileChannel中数据放入ByteBuffer中
while (fChannel.read(bbuff) != -1) {
// 锁定Buffer的空白区
// limit移动到原来position位置,limit后面数据无法读写,
// 这样就不会读到空数据了
bbuff.flip();
// 创建Charset对象
Charset charset = Charset.forName(targetEncode);
// 创建解码器(CharsetDecoder)对象
CharsetDecoder decoder = charset.newDecoder();
// 将ByteBuffer的内容转码
CharBuffer cbuff = decoder.decode(bbuff);
// System.out.print(cbuff);
// str = cbuff.toString();
sBuilder.append(cbuff.toString());
// 将Buffer初始化,为下一次读取数据做准备
// 将position位置置为0,limit置为capacity
bbuff.clear();
}
} catch (Exception e) {
// TODO: handle exception
} finally {
// 关闭流
try {
fis.close();
fChannel.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return sBuilder.toString();
}
/**
* 字符串 写入到 CharBuffer 再通过Charset转为 ByteBuffer,最后写入到FileChannel
*
* Channel写入字符串到文件
* @param content 字符串
* @param targetFile 保存的文件名称
* @param targetEncode 编码
*/
public static void channelWrite(String content, String targetFile, String targetEncode) {
// 不使用java7的try()处理方法
FileChannel outChannel = null;
FileOutputStream outStream = null;
//
Charset charset = Charset.forName(targetEncode);
CharsetEncoder encoder = charset.newEncoder(); // 编码
// CharsetDecoder decoder = charset.newDecoder(); // 解码
try {
outStream = new FileOutputStream(targetFile);
// 以文件输出流创建FileBuffer,用以控制输出
outChannel = outStream.getChannel();
// 定义一个ByteBuffer对象,用于重复取水
//容量刚好是字符串长度
CharBuffer charBuff = CharBuffer.allocate(content.length());
int capacity = charBuff.capacity();
System.out.println("容量:"+capacity);
// 遍历字符串内容
for (int i = 0; i < content.length(); i++) {
if (capacity>=content.length()) {
charBuff.put(content.charAt(i));
}
//错误写法 buffer最后只有一个字符
// else {
// // 将Buffer初始化,为下一次读取数据做准备
// // 将position位置置为0,limit置为capacity
// charBuff.clear();
// charBuff.put(content.charAt(i));
// }
System.out.println(content.charAt(i));
}
// 锁定Buffer空白区
charBuff.flip();
// CharBuffer字符序列转字节序列
ByteBuffer byteBuffer = encoder.encode(charBuff);
// //byteBuffer.flip(); //不能加
// ByteBuffer写入到Channel
// 直接将buffer里的数据全部输出
outChannel.write(byteBuffer);
// //访问ByteBuffer的每个字节
// for (int i = 0; i < byteBuffer.capacity(); i++) {
// System.out.println(byteBuffer.get(i)+" ");
// }
// //ByteBuffer字节序列转字符序列
// System.out.println("\n"+decoder.decode(byteBuffer));
// 将Buffer初始化,为下一次读取数据做准备
// 将position位置置为0,limit置为capacity
charBuff.clear();
byteBuffer.clear();
} catch (Exception e) {
// TODO: handle exception
} finally {
// 关闭流
try {
outStream.close();
outChannel.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 指定内容添加到文件中
* @param content
* @param targetFile
* @param targetEncode
*/
public static void channelAppend(String content ,
String targetFile, String targetEncode) {
Charset charset = Charset.forName(targetEncode);
CharsetEncoder encoder = charset.newEncoder(); // 编码
try {
File f = new File(targetFile);
// Java7 新增 try后面加的括号
// 括号里面是必须显式关闭的物理资源,如数据库连接、网络连接、磁盘文件
// 在try语句结束时自动关闭该资源,不需要finally 判断关闭了
try(
// 创建一个RandomAccessFile对象 可读写模式
RandomAccessFile raf = new RandomAccessFile(f, "rw");
// 获取RandomAccessFile对应的Channel
FileChannel randomChannel = raf.getChannel())
{
// 将Channel中所有数据映射成ByteBuffer
// ByteBuffer buffer = randomChannel.map(FileChannel
// .MapMode.READ_ONLY, 0 , f.length());
// 定义一个ByteBuffer对象,用于重复取水
//容量刚好是字符串长度
CharBuffer charBuff = CharBuffer.allocate(content.length());
int capacity = charBuff.capacity();
System.out.println("容量:"+capacity);
// 遍历字符串内容
for (int i = 0; i < content.length(); i++) {
if (capacity>=content.length()) {
charBuff.put(content.charAt(i));
}
System.out.println(content.charAt(i));
}
charBuff.flip();
// CharBuffer字符序列转字节序列
ByteBuffer byteBuffer = encoder.encode(charBuff);
//byteBuffer.flip(); //不能加
// 把Channel的记录指针移动到最后
randomChannel.position(f.length());
//
// 将buffer中所有数据输出
randomChannel.write(byteBuffer);
// 将Buffer初始化,为下一次读取数据做准备
// 将position位置置为0,limit置为capacity
charBuff.clear();
byteBuffer.clear();
}
} catch (Exception e) {
// TODO: handle exception
}
}
}