贴一个旧解法:
public static String SplitString(String str, int bytes) {
int count = 0; //统计字节数
String reStr = ""; //返回字符串
if (str == null) {
return "";
}
char[] tempChar = str.toCharArray();
for (int i = 0; i < tempChar.length; i++) {
String s1 = str.valueOf(tempChar[i]);
byte[] b = s1.getBytes();
count += b.length;
if (count <= bytes) {
reStr += tempChar[i];
}
}
return reStr;
}
14 个解决方案
#1
不明白为什么你要那样截取。。
#2
诡异的需求,string存的是unicode,确定按奇数字节拆了还有意义? 如果string里是单纯的字节流,那当初为何不用byte[]存呢。
#3
一个接口的参数要求不得超过10240字节。如超过10240,截取前10240字节发送。
#4
一个接口的参数要求不得超过10240字节。如超过10240,截取前10240字节发送。
#5
一个接口的参数要求不得超过10240字节。如超过10240,截取前10240字节发送。
#6
觉着你以前的那地方有两个地方可以处理下
一个是当达到bytes大小后直接break(减少不必要的循环)
一个是String的拼接改用StringBuffer(减少string +创建的新对象)
另一个方法直接获得byte数组(减少循环次数和字符串的拼接次数)
直接获取你上面的bytes位置的那个字节是是占的汉字还是其他
然后自己是去掉还是加上就看自己需要
一个是当达到bytes大小后直接break(减少不必要的循环)
一个是String的拼接改用StringBuffer(减少string +创建的新对象)
另一个方法直接获得byte数组(减少循环次数和字符串的拼接次数)
直接获取你上面的bytes位置的那个字节是是占的汉字还是其他
然后自己是去掉还是加上就看自己需要
#7
你都用toCharArray了,为什么不直接getBytes?然后用copyArray截取得到的byte数组不就行了?
#8
第二种方法要怎么判断最后的字节是汉字的一半还是一个英文字符?
#9
如果copy到最后一个字节是字符的一半怎么办
#10
根据你的编码来判断是不是一个完整字符啊。。
比如UTF-8编码,单字节字符0xxxxxxx,双字节110xxxxx 10xxxxxx
三字节1110xxxx 10xxxxxx 10xxxxxx,四字节11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
#11
觉着你以前的那地方有两个地方可以处理下
一个是当达到bytes大小后直接break(减少不必要的循环)
一个是String的拼接改用StringBuffer(减少string +创建的新对象)
另一个方法直接获得byte数组(减少循环次数和字符串的拼接次数)
直接获取你上面的bytes位置的那个字节是是占的汉字还是其他
然后自己是去掉还是加上就看自己需要
第二种方法要怎么判断最后的字节是汉字的一半还是一个英文字符?
大于0x80为双字节字符,否则为单字节字符==我直接搜的 你自己确定是不是吧
#13
可以这样尝试:
1、取前10240字节构造一个字符串tmp
2、tmp取最后一个字符做字符串,再次getBytes 得到 byte[] arr1。tmp除了最后一个字符的前面字符串getBytes 得到 byte[] arr2
3、如果arr1.length + arr2.length != 10240,直接返回tmp除了最后一个字符的前面字符串
4、如果如果相等对arr1和10240最后arr1.length的字节比较,如果一样说明前10240正好是个无乱码的字符串。如果不一样返回tmp除了最后一个字符的前面字符串。
还没验证可行性。其实从效率上感觉不一定比你现在的方法好,你现在的访问需要做些修改。
1、每次取一个字符转换为字符串getbyte应该直接用substring来获得一个特定字节的String对象
其他如u010479715所说:
一个是当达到bytes大小后直接break(减少不必要的循环)
一个是String的拼接改用StringBuffer(减少string +创建的新对象) , 这里如果是单线程的话用StringBuilder
1、取前10240字节构造一个字符串tmp
2、tmp取最后一个字符做字符串,再次getBytes 得到 byte[] arr1。tmp除了最后一个字符的前面字符串getBytes 得到 byte[] arr2
3、如果arr1.length + arr2.length != 10240,直接返回tmp除了最后一个字符的前面字符串
4、如果如果相等对arr1和10240最后arr1.length的字节比较,如果一样说明前10240正好是个无乱码的字符串。如果不一样返回tmp除了最后一个字符的前面字符串。
还没验证可行性。其实从效率上感觉不一定比你现在的方法好,你现在的访问需要做些修改。
1、每次取一个字符转换为字符串getbyte应该直接用substring来获得一个特定字节的String对象
其他如u010479715所说:
一个是当达到bytes大小后直接break(减少不必要的循环)
一个是String的拼接改用StringBuffer(减少string +创建的新对象) , 这里如果是单线程的话用StringBuilder
#14
// 导入java.util下的所有类
import java.io.*;
/**
* Description:
* <br>Webside: <a href="https://github.com/zallerting">GitHub Of ZallerTing</a>
* <br>Date: 2016-12-21
* @author Zaller.Ting zallerting@gmail.com
* @version 1.0
* 微信/Wechat: ZALLER-TING
* QQ: 851509660
* Location:Kunshan
* 实现输入(待截取字串,开始截取字节索引,截取字节长度)后,输出截取字节长度子串,不出现半个中文字符(?)
*/
public class CutStringByByte {
// 表示开始截取字节索引,首字符索引,字串最大长度,字串最大字节长度,子串长度,子串字节长度,前部分截取字节长度,截取字节长度,半个中文字符数量,临时变量
protected static int startByteIndex, firstStrIndex, maxStrLen, maxByteLen, subLen, subByteLen, beforeCutByteLen, cutByteLen, halfHanNum, tmp;
// 表示键盘输入的一行数据,待截取字串,截取子串变量
protected static String inputStr, beCutStr, subStr;
// 表示键盘输入的单个字符变量
protected static char ch;
// 表示键盘输入的一行数据组成的数组
protected static String[] inputStrArr;
// 表示以GBK编码方式解析的字节数组
protected static byte bytesByGBK[];
// 判断截取字节索引及截取字节长度是否在有效范围
protected static boolean isProperIndex, isProperLen;
// 判断是否为数值型字符串的方法(正数)
protected static boolean isNumbericStr(String inputStr) {
for(int i = 0; i < inputStr.length(); i++) {
// 返回指定索引处的字符
ch = inputStr.charAt(i);
if(ch < 46 || ch > 57) {
return false;
}
}
return true;
}
// 判断是否为数值型字符串的方法(负数)
protected static boolean isNegativeStr(String inputStr) {
ch = inputStr.charAt(0);
if(ch == '-') {
return true;
}
return false;
}
// 统计半个中文字符的数量
protected static int halfHanNum(int startByteIndex) {
// 初始化halfHanNum变量
halfHanNum = 0;
for(int i = 0; i <= startByteIndex; i++) {
// 字节索引对应值小于0时halfHanNum加1
if(bytesByGBK[i] < 0) {
++halfHanNum;
}
}
return halfHanNum;
}
// 找出需要截取子串第1个字符索引
protected static int find1stStrIndex(int startByteIndex, String subStr) {
// 统计半个中文字符的数量
halfHanNum(startByteIndex);
// startByteIndex字节索引对应字符为非中文单字节字符, 取subStr最后1个字符
if(bytesByGBK[startByteIndex] > 0) {
firstStrIndex = subStr.length() > 0 ? subStr.length() - 1 : 0;
// startByteIndex字节索引为中文字符第1个字节, 取subStr后面1个字符
} else if(halfHanNum % 2 == 1){
firstStrIndex = subStr.length();
// startByteIndex字节索引为中文字符第2个字节, 取subStr后面1个字符
} else if(halfHanNum % 2 == 0){
firstStrIndex = subStr.length();
}
return firstStrIndex;
}
// 从指定字节索引startByteIndex截取cutByteLen长度的子串方法
public static void subStr(String beCutStr, int startByteIndex, int cutByteLen) throws IOException {
/**
* 分两部分计算:
* 一.截取从索引startByteIndex开始的maxStrLen长度的子串:
* 1.截取从索引0开始的startByteIndex+1长度的子串;
* 2.找出需要截取子串的第1个字符索引firstStrIndex;
* 3.截取从索引firstStrIndex开始的maxStrLen长度的子串;
*
* 二.截取从索引startByteIndex开始的cutByteLen长度的子串:
* 1.重新计算需要截取字串最大长度maxStrLen;
* 2.截取从索引firstStrIndex开始的cutByteLen长度的子串;
* 3.返回从startByteIndex字节索引截取cutByteLen长度的子串subStr;
*/
/**
* 第一部分:截取从索引startByteIndex开始的maxStrLen长度的子串
*/
// 字串最大长度
maxStrLen = beCutStr.length();
// 字串最大字节长度
maxByteLen = beCutStr.getBytes().length;
// 前一部分截取字节长度
beforeCutByteLen = startByteIndex > 0 ? startByteIndex + 1 : 0;
// 从索引[0]截取长度[beforeCutByteLen]的子串
subStr = beCutStr.substring(0, beforeCutByteLen > maxStrLen ? maxStrLen : beforeCutByteLen);
// 子串字节长度
subByteLen = subStr.getBytes("GBK").length;
// 子串字节长度赋给临时变量tmp
tmp = subByteLen;
// 前部分截取字节长度小于子串字节长度时
while(beforeCutByteLen < subByteLen) {
// 临时变量减1
--tmp;
subStr = beCutStr.substring(0, tmp > maxStrLen ? maxStrLen : tmp);
subByteLen = subStr.getBytes("GBK").length;
}
// 找出需要截取子串第1个字符索引
find1stStrIndex(startByteIndex, subStr);
// 找出需要截取子串
subStr = beCutStr.substring(firstStrIndex, maxStrLen);
/**
* 第二部分:截取从索引startByteIndex开始的cutByteLen长度的子串
*/
// 子串字节长度
subByteLen = subStr.getBytes("GBK").length;
// 重新计算需要截取字串最大长度
maxStrLen = maxStrLen - firstStrIndex;
// 子串字节长度赋给临时变量tmp
tmp = subByteLen;
// 需要截取字节长度小于子串字节长度时
while(cutByteLen < subByteLen) {
// 需要截取字节长度减1
--tmp;
subStr = subStr.substring(0, tmp > maxStrLen ? maxStrLen : tmp);
subByteLen = subStr.getBytes("GBK").length;
}
System.out.println("“" + beCutStr + "” 从第" + startByteIndex + "字节索引截取" + cutByteLen + "字节的子串为: " + subStr + "\n");
}
// 主方法,程序的入口
public static void main(String[] args) throws IOException {
System.out.println("【本软件实现从指定字节索引截取指定字节长度子串的功能】\n");
System.out.print(" 以【待截字串,开始截取字节索引,截取字节长度】格式输入 :");
// 获取键盘输入字符串
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while((inputStr = br.readLine()) != null) {
// 通过英文逗号分隔键盘输入的字符串
inputStrArr = inputStr.split(",");
// 将键盘输入的第1个参数以"GBK"编码形式译码成1个字节数组
bytesByGBK = inputStrArr[0].getBytes("GBK");
// 判断是否键盘输入包含英文逗号且以逗号分隔的字符串中第1个不为null
if(inputStr.contains(",") && !inputStr.contains(",") && inputStrArr[0] != null) {
// 判断是否键盘输入第2个及第3个均为数值型字符串
if(isNumbericStr(inputStrArr[1]) && isNumbericStr(inputStrArr[2])) {
// 转换数值型字符串为对应数值
startByteIndex = Integer.parseInt(inputStrArr[1]);
cutByteLen = Integer.parseInt(inputStrArr[2]);
// 判断键盘输入的第2个及第3个数值是否在合理范围内
isProperIndex = startByteIndex >= 0 && startByteIndex <= bytesByGBK.length ? true : false;
isProperLen = cutByteLen >= 0 && cutByteLen <= bytesByGBK.length - startByteIndex ? true : false;
// 再判断截取字串字节索引及字节长度是否正确
if(isProperIndex) {
if(isProperLen) {
// 从指定索引位置截取指定字节长度的子串
subStr(inputStrArr[0], startByteIndex, cutByteLen);
} else {
System.out.println("截取字节长度输入有误!");
}
} else {
System.out.println("开始截取字节索引输入有误!");
}
// 判断是否键盘输入第2个及第3个均为负数值型字符串
} else if(isNegativeStr(inputStrArr[1]) && isNegativeStr(inputStrArr[2])){
System.out.println("开始截取字节索引及截取字节长度均输入有误!");
} else if(isNegativeStr(inputStrArr[1]) && !isNegativeStr(inputStrArr[2])){
System.out.println("开始截取字节索引输入有误!");
} else if(!isNegativeStr(inputStrArr[1]) && isNegativeStr(inputStrArr[2])){
System.out.println("截取字节长度输入有误!");
}
// 判断是否键盘输入包含中文逗号
} else if(inputStr.contains(",")) {
System.out.println("请以英文逗号分隔字串、字节索引、字节长度!");
} else {
System.out.println("待截取字串输入为空!");
}
System.out.print(" 以【待截字串,开始截取字节索引,截取字节长度】格式输入 :");
}
}
}
import java.io.*;
/**
* Description:
* <br>Webside: <a href="https://github.com/zallerting">GitHub Of ZallerTing</a>
* <br>Date: 2016-12-21
* @author Zaller.Ting zallerting@gmail.com
* @version 1.0
* 微信/Wechat: ZALLER-TING
* QQ: 851509660
* Location:Kunshan
* 实现输入(待截取字串,开始截取字节索引,截取字节长度)后,输出截取字节长度子串,不出现半个中文字符(?)
*/
public class CutStringByByte {
// 表示开始截取字节索引,首字符索引,字串最大长度,字串最大字节长度,子串长度,子串字节长度,前部分截取字节长度,截取字节长度,半个中文字符数量,临时变量
protected static int startByteIndex, firstStrIndex, maxStrLen, maxByteLen, subLen, subByteLen, beforeCutByteLen, cutByteLen, halfHanNum, tmp;
// 表示键盘输入的一行数据,待截取字串,截取子串变量
protected static String inputStr, beCutStr, subStr;
// 表示键盘输入的单个字符变量
protected static char ch;
// 表示键盘输入的一行数据组成的数组
protected static String[] inputStrArr;
// 表示以GBK编码方式解析的字节数组
protected static byte bytesByGBK[];
// 判断截取字节索引及截取字节长度是否在有效范围
protected static boolean isProperIndex, isProperLen;
// 判断是否为数值型字符串的方法(正数)
protected static boolean isNumbericStr(String inputStr) {
for(int i = 0; i < inputStr.length(); i++) {
// 返回指定索引处的字符
ch = inputStr.charAt(i);
if(ch < 46 || ch > 57) {
return false;
}
}
return true;
}
// 判断是否为数值型字符串的方法(负数)
protected static boolean isNegativeStr(String inputStr) {
ch = inputStr.charAt(0);
if(ch == '-') {
return true;
}
return false;
}
// 统计半个中文字符的数量
protected static int halfHanNum(int startByteIndex) {
// 初始化halfHanNum变量
halfHanNum = 0;
for(int i = 0; i <= startByteIndex; i++) {
// 字节索引对应值小于0时halfHanNum加1
if(bytesByGBK[i] < 0) {
++halfHanNum;
}
}
return halfHanNum;
}
// 找出需要截取子串第1个字符索引
protected static int find1stStrIndex(int startByteIndex, String subStr) {
// 统计半个中文字符的数量
halfHanNum(startByteIndex);
// startByteIndex字节索引对应字符为非中文单字节字符, 取subStr最后1个字符
if(bytesByGBK[startByteIndex] > 0) {
firstStrIndex = subStr.length() > 0 ? subStr.length() - 1 : 0;
// startByteIndex字节索引为中文字符第1个字节, 取subStr后面1个字符
} else if(halfHanNum % 2 == 1){
firstStrIndex = subStr.length();
// startByteIndex字节索引为中文字符第2个字节, 取subStr后面1个字符
} else if(halfHanNum % 2 == 0){
firstStrIndex = subStr.length();
}
return firstStrIndex;
}
// 从指定字节索引startByteIndex截取cutByteLen长度的子串方法
public static void subStr(String beCutStr, int startByteIndex, int cutByteLen) throws IOException {
/**
* 分两部分计算:
* 一.截取从索引startByteIndex开始的maxStrLen长度的子串:
* 1.截取从索引0开始的startByteIndex+1长度的子串;
* 2.找出需要截取子串的第1个字符索引firstStrIndex;
* 3.截取从索引firstStrIndex开始的maxStrLen长度的子串;
*
* 二.截取从索引startByteIndex开始的cutByteLen长度的子串:
* 1.重新计算需要截取字串最大长度maxStrLen;
* 2.截取从索引firstStrIndex开始的cutByteLen长度的子串;
* 3.返回从startByteIndex字节索引截取cutByteLen长度的子串subStr;
*/
/**
* 第一部分:截取从索引startByteIndex开始的maxStrLen长度的子串
*/
// 字串最大长度
maxStrLen = beCutStr.length();
// 字串最大字节长度
maxByteLen = beCutStr.getBytes().length;
// 前一部分截取字节长度
beforeCutByteLen = startByteIndex > 0 ? startByteIndex + 1 : 0;
// 从索引[0]截取长度[beforeCutByteLen]的子串
subStr = beCutStr.substring(0, beforeCutByteLen > maxStrLen ? maxStrLen : beforeCutByteLen);
// 子串字节长度
subByteLen = subStr.getBytes("GBK").length;
// 子串字节长度赋给临时变量tmp
tmp = subByteLen;
// 前部分截取字节长度小于子串字节长度时
while(beforeCutByteLen < subByteLen) {
// 临时变量减1
--tmp;
subStr = beCutStr.substring(0, tmp > maxStrLen ? maxStrLen : tmp);
subByteLen = subStr.getBytes("GBK").length;
}
// 找出需要截取子串第1个字符索引
find1stStrIndex(startByteIndex, subStr);
// 找出需要截取子串
subStr = beCutStr.substring(firstStrIndex, maxStrLen);
/**
* 第二部分:截取从索引startByteIndex开始的cutByteLen长度的子串
*/
// 子串字节长度
subByteLen = subStr.getBytes("GBK").length;
// 重新计算需要截取字串最大长度
maxStrLen = maxStrLen - firstStrIndex;
// 子串字节长度赋给临时变量tmp
tmp = subByteLen;
// 需要截取字节长度小于子串字节长度时
while(cutByteLen < subByteLen) {
// 需要截取字节长度减1
--tmp;
subStr = subStr.substring(0, tmp > maxStrLen ? maxStrLen : tmp);
subByteLen = subStr.getBytes("GBK").length;
}
System.out.println("“" + beCutStr + "” 从第" + startByteIndex + "字节索引截取" + cutByteLen + "字节的子串为: " + subStr + "\n");
}
// 主方法,程序的入口
public static void main(String[] args) throws IOException {
System.out.println("【本软件实现从指定字节索引截取指定字节长度子串的功能】\n");
System.out.print(" 以【待截字串,开始截取字节索引,截取字节长度】格式输入 :");
// 获取键盘输入字符串
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while((inputStr = br.readLine()) != null) {
// 通过英文逗号分隔键盘输入的字符串
inputStrArr = inputStr.split(",");
// 将键盘输入的第1个参数以"GBK"编码形式译码成1个字节数组
bytesByGBK = inputStrArr[0].getBytes("GBK");
// 判断是否键盘输入包含英文逗号且以逗号分隔的字符串中第1个不为null
if(inputStr.contains(",") && !inputStr.contains(",") && inputStrArr[0] != null) {
// 判断是否键盘输入第2个及第3个均为数值型字符串
if(isNumbericStr(inputStrArr[1]) && isNumbericStr(inputStrArr[2])) {
// 转换数值型字符串为对应数值
startByteIndex = Integer.parseInt(inputStrArr[1]);
cutByteLen = Integer.parseInt(inputStrArr[2]);
// 判断键盘输入的第2个及第3个数值是否在合理范围内
isProperIndex = startByteIndex >= 0 && startByteIndex <= bytesByGBK.length ? true : false;
isProperLen = cutByteLen >= 0 && cutByteLen <= bytesByGBK.length - startByteIndex ? true : false;
// 再判断截取字串字节索引及字节长度是否正确
if(isProperIndex) {
if(isProperLen) {
// 从指定索引位置截取指定字节长度的子串
subStr(inputStrArr[0], startByteIndex, cutByteLen);
} else {
System.out.println("截取字节长度输入有误!");
}
} else {
System.out.println("开始截取字节索引输入有误!");
}
// 判断是否键盘输入第2个及第3个均为负数值型字符串
} else if(isNegativeStr(inputStrArr[1]) && isNegativeStr(inputStrArr[2])){
System.out.println("开始截取字节索引及截取字节长度均输入有误!");
} else if(isNegativeStr(inputStrArr[1]) && !isNegativeStr(inputStrArr[2])){
System.out.println("开始截取字节索引输入有误!");
} else if(!isNegativeStr(inputStrArr[1]) && isNegativeStr(inputStrArr[2])){
System.out.println("截取字节长度输入有误!");
}
// 判断是否键盘输入包含中文逗号
} else if(inputStr.contains(",")) {
System.out.println("请以英文逗号分隔字串、字节索引、字节长度!");
} else {
System.out.println("待截取字串输入为空!");
}
System.out.print(" 以【待截字串,开始截取字节索引,截取字节长度】格式输入 :");
}
}
}
#1
不明白为什么你要那样截取。。
#2
诡异的需求,string存的是unicode,确定按奇数字节拆了还有意义? 如果string里是单纯的字节流,那当初为何不用byte[]存呢。
#3
一个接口的参数要求不得超过10240字节。如超过10240,截取前10240字节发送。
#4
诡异的需求,string存的是unicode,确定按奇数字节拆了还有意义? 如果string里是单纯的字节流,那当初为何不用byte[]存呢。
一个接口的参数要求不得超过10240字节。如超过10240,截取前10240字节发送。
#5
不明白为什么你要那样截取。。
一个接口的参数要求不得超过10240字节。如超过10240,截取前10240字节发送。
#6
觉着你以前的那地方有两个地方可以处理下
一个是当达到bytes大小后直接break(减少不必要的循环)
一个是String的拼接改用StringBuffer(减少string +创建的新对象)
另一个方法直接获得byte数组(减少循环次数和字符串的拼接次数)
直接获取你上面的bytes位置的那个字节是是占的汉字还是其他
然后自己是去掉还是加上就看自己需要
一个是当达到bytes大小后直接break(减少不必要的循环)
一个是String的拼接改用StringBuffer(减少string +创建的新对象)
另一个方法直接获得byte数组(减少循环次数和字符串的拼接次数)
直接获取你上面的bytes位置的那个字节是是占的汉字还是其他
然后自己是去掉还是加上就看自己需要
#7
你都用toCharArray了,为什么不直接getBytes?然后用copyArray截取得到的byte数组不就行了?
#8
觉着你以前的那地方有两个地方可以处理下
一个是当达到bytes大小后直接break(减少不必要的循环)
一个是String的拼接改用StringBuffer(减少string +创建的新对象)
另一个方法直接获得byte数组(减少循环次数和字符串的拼接次数)
直接获取你上面的bytes位置的那个字节是是占的汉字还是其他
然后自己是去掉还是加上就看自己需要
第二种方法要怎么判断最后的字节是汉字的一半还是一个英文字符?
#9
你都用toCharArray了,为什么不直接getBytes?然后用copyArray截取得到的byte数组不就行了?
如果copy到最后一个字节是字符的一半怎么办
#10
你都用toCharArray了,为什么不直接getBytes?然后用copyArray截取得到的byte数组不就行了?
如果copy到最后一个字节是字符的一半怎么办
根据你的编码来判断是不是一个完整字符啊。。
比如UTF-8编码,单字节字符0xxxxxxx,双字节110xxxxx 10xxxxxx
三字节1110xxxx 10xxxxxx 10xxxxxx,四字节11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
#11
觉着你以前的那地方有两个地方可以处理下
一个是当达到bytes大小后直接break(减少不必要的循环)
一个是String的拼接改用StringBuffer(减少string +创建的新对象)
另一个方法直接获得byte数组(减少循环次数和字符串的拼接次数)
直接获取你上面的bytes位置的那个字节是是占的汉字还是其他
然后自己是去掉还是加上就看自己需要
第二种方法要怎么判断最后的字节是汉字的一半还是一个英文字符?
大于0x80为双字节字符,否则为单字节字符==我直接搜的 你自己确定是不是吧
#12
#13
可以这样尝试:
1、取前10240字节构造一个字符串tmp
2、tmp取最后一个字符做字符串,再次getBytes 得到 byte[] arr1。tmp除了最后一个字符的前面字符串getBytes 得到 byte[] arr2
3、如果arr1.length + arr2.length != 10240,直接返回tmp除了最后一个字符的前面字符串
4、如果如果相等对arr1和10240最后arr1.length的字节比较,如果一样说明前10240正好是个无乱码的字符串。如果不一样返回tmp除了最后一个字符的前面字符串。
还没验证可行性。其实从效率上感觉不一定比你现在的方法好,你现在的访问需要做些修改。
1、每次取一个字符转换为字符串getbyte应该直接用substring来获得一个特定字节的String对象
其他如u010479715所说:
一个是当达到bytes大小后直接break(减少不必要的循环)
一个是String的拼接改用StringBuffer(减少string +创建的新对象) , 这里如果是单线程的话用StringBuilder
1、取前10240字节构造一个字符串tmp
2、tmp取最后一个字符做字符串,再次getBytes 得到 byte[] arr1。tmp除了最后一个字符的前面字符串getBytes 得到 byte[] arr2
3、如果arr1.length + arr2.length != 10240,直接返回tmp除了最后一个字符的前面字符串
4、如果如果相等对arr1和10240最后arr1.length的字节比较,如果一样说明前10240正好是个无乱码的字符串。如果不一样返回tmp除了最后一个字符的前面字符串。
还没验证可行性。其实从效率上感觉不一定比你现在的方法好,你现在的访问需要做些修改。
1、每次取一个字符转换为字符串getbyte应该直接用substring来获得一个特定字节的String对象
其他如u010479715所说:
一个是当达到bytes大小后直接break(减少不必要的循环)
一个是String的拼接改用StringBuffer(减少string +创建的新对象) , 这里如果是单线程的话用StringBuilder
#14
// 导入java.util下的所有类
import java.io.*;
/**
* Description:
* <br>Webside: <a href="https://github.com/zallerting">GitHub Of ZallerTing</a>
* <br>Date: 2016-12-21
* @author Zaller.Ting zallerting@gmail.com
* @version 1.0
* 微信/Wechat: ZALLER-TING
* QQ: 851509660
* Location:Kunshan
* 实现输入(待截取字串,开始截取字节索引,截取字节长度)后,输出截取字节长度子串,不出现半个中文字符(?)
*/
public class CutStringByByte {
// 表示开始截取字节索引,首字符索引,字串最大长度,字串最大字节长度,子串长度,子串字节长度,前部分截取字节长度,截取字节长度,半个中文字符数量,临时变量
protected static int startByteIndex, firstStrIndex, maxStrLen, maxByteLen, subLen, subByteLen, beforeCutByteLen, cutByteLen, halfHanNum, tmp;
// 表示键盘输入的一行数据,待截取字串,截取子串变量
protected static String inputStr, beCutStr, subStr;
// 表示键盘输入的单个字符变量
protected static char ch;
// 表示键盘输入的一行数据组成的数组
protected static String[] inputStrArr;
// 表示以GBK编码方式解析的字节数组
protected static byte bytesByGBK[];
// 判断截取字节索引及截取字节长度是否在有效范围
protected static boolean isProperIndex, isProperLen;
// 判断是否为数值型字符串的方法(正数)
protected static boolean isNumbericStr(String inputStr) {
for(int i = 0; i < inputStr.length(); i++) {
// 返回指定索引处的字符
ch = inputStr.charAt(i);
if(ch < 46 || ch > 57) {
return false;
}
}
return true;
}
// 判断是否为数值型字符串的方法(负数)
protected static boolean isNegativeStr(String inputStr) {
ch = inputStr.charAt(0);
if(ch == '-') {
return true;
}
return false;
}
// 统计半个中文字符的数量
protected static int halfHanNum(int startByteIndex) {
// 初始化halfHanNum变量
halfHanNum = 0;
for(int i = 0; i <= startByteIndex; i++) {
// 字节索引对应值小于0时halfHanNum加1
if(bytesByGBK[i] < 0) {
++halfHanNum;
}
}
return halfHanNum;
}
// 找出需要截取子串第1个字符索引
protected static int find1stStrIndex(int startByteIndex, String subStr) {
// 统计半个中文字符的数量
halfHanNum(startByteIndex);
// startByteIndex字节索引对应字符为非中文单字节字符, 取subStr最后1个字符
if(bytesByGBK[startByteIndex] > 0) {
firstStrIndex = subStr.length() > 0 ? subStr.length() - 1 : 0;
// startByteIndex字节索引为中文字符第1个字节, 取subStr后面1个字符
} else if(halfHanNum % 2 == 1){
firstStrIndex = subStr.length();
// startByteIndex字节索引为中文字符第2个字节, 取subStr后面1个字符
} else if(halfHanNum % 2 == 0){
firstStrIndex = subStr.length();
}
return firstStrIndex;
}
// 从指定字节索引startByteIndex截取cutByteLen长度的子串方法
public static void subStr(String beCutStr, int startByteIndex, int cutByteLen) throws IOException {
/**
* 分两部分计算:
* 一.截取从索引startByteIndex开始的maxStrLen长度的子串:
* 1.截取从索引0开始的startByteIndex+1长度的子串;
* 2.找出需要截取子串的第1个字符索引firstStrIndex;
* 3.截取从索引firstStrIndex开始的maxStrLen长度的子串;
*
* 二.截取从索引startByteIndex开始的cutByteLen长度的子串:
* 1.重新计算需要截取字串最大长度maxStrLen;
* 2.截取从索引firstStrIndex开始的cutByteLen长度的子串;
* 3.返回从startByteIndex字节索引截取cutByteLen长度的子串subStr;
*/
/**
* 第一部分:截取从索引startByteIndex开始的maxStrLen长度的子串
*/
// 字串最大长度
maxStrLen = beCutStr.length();
// 字串最大字节长度
maxByteLen = beCutStr.getBytes().length;
// 前一部分截取字节长度
beforeCutByteLen = startByteIndex > 0 ? startByteIndex + 1 : 0;
// 从索引[0]截取长度[beforeCutByteLen]的子串
subStr = beCutStr.substring(0, beforeCutByteLen > maxStrLen ? maxStrLen : beforeCutByteLen);
// 子串字节长度
subByteLen = subStr.getBytes("GBK").length;
// 子串字节长度赋给临时变量tmp
tmp = subByteLen;
// 前部分截取字节长度小于子串字节长度时
while(beforeCutByteLen < subByteLen) {
// 临时变量减1
--tmp;
subStr = beCutStr.substring(0, tmp > maxStrLen ? maxStrLen : tmp);
subByteLen = subStr.getBytes("GBK").length;
}
// 找出需要截取子串第1个字符索引
find1stStrIndex(startByteIndex, subStr);
// 找出需要截取子串
subStr = beCutStr.substring(firstStrIndex, maxStrLen);
/**
* 第二部分:截取从索引startByteIndex开始的cutByteLen长度的子串
*/
// 子串字节长度
subByteLen = subStr.getBytes("GBK").length;
// 重新计算需要截取字串最大长度
maxStrLen = maxStrLen - firstStrIndex;
// 子串字节长度赋给临时变量tmp
tmp = subByteLen;
// 需要截取字节长度小于子串字节长度时
while(cutByteLen < subByteLen) {
// 需要截取字节长度减1
--tmp;
subStr = subStr.substring(0, tmp > maxStrLen ? maxStrLen : tmp);
subByteLen = subStr.getBytes("GBK").length;
}
System.out.println("“" + beCutStr + "” 从第" + startByteIndex + "字节索引截取" + cutByteLen + "字节的子串为: " + subStr + "\n");
}
// 主方法,程序的入口
public static void main(String[] args) throws IOException {
System.out.println("【本软件实现从指定字节索引截取指定字节长度子串的功能】\n");
System.out.print(" 以【待截字串,开始截取字节索引,截取字节长度】格式输入 :");
// 获取键盘输入字符串
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while((inputStr = br.readLine()) != null) {
// 通过英文逗号分隔键盘输入的字符串
inputStrArr = inputStr.split(",");
// 将键盘输入的第1个参数以"GBK"编码形式译码成1个字节数组
bytesByGBK = inputStrArr[0].getBytes("GBK");
// 判断是否键盘输入包含英文逗号且以逗号分隔的字符串中第1个不为null
if(inputStr.contains(",") && !inputStr.contains(",") && inputStrArr[0] != null) {
// 判断是否键盘输入第2个及第3个均为数值型字符串
if(isNumbericStr(inputStrArr[1]) && isNumbericStr(inputStrArr[2])) {
// 转换数值型字符串为对应数值
startByteIndex = Integer.parseInt(inputStrArr[1]);
cutByteLen = Integer.parseInt(inputStrArr[2]);
// 判断键盘输入的第2个及第3个数值是否在合理范围内
isProperIndex = startByteIndex >= 0 && startByteIndex <= bytesByGBK.length ? true : false;
isProperLen = cutByteLen >= 0 && cutByteLen <= bytesByGBK.length - startByteIndex ? true : false;
// 再判断截取字串字节索引及字节长度是否正确
if(isProperIndex) {
if(isProperLen) {
// 从指定索引位置截取指定字节长度的子串
subStr(inputStrArr[0], startByteIndex, cutByteLen);
} else {
System.out.println("截取字节长度输入有误!");
}
} else {
System.out.println("开始截取字节索引输入有误!");
}
// 判断是否键盘输入第2个及第3个均为负数值型字符串
} else if(isNegativeStr(inputStrArr[1]) && isNegativeStr(inputStrArr[2])){
System.out.println("开始截取字节索引及截取字节长度均输入有误!");
} else if(isNegativeStr(inputStrArr[1]) && !isNegativeStr(inputStrArr[2])){
System.out.println("开始截取字节索引输入有误!");
} else if(!isNegativeStr(inputStrArr[1]) && isNegativeStr(inputStrArr[2])){
System.out.println("截取字节长度输入有误!");
}
// 判断是否键盘输入包含中文逗号
} else if(inputStr.contains(",")) {
System.out.println("请以英文逗号分隔字串、字节索引、字节长度!");
} else {
System.out.println("待截取字串输入为空!");
}
System.out.print(" 以【待截字串,开始截取字节索引,截取字节长度】格式输入 :");
}
}
}
import java.io.*;
/**
* Description:
* <br>Webside: <a href="https://github.com/zallerting">GitHub Of ZallerTing</a>
* <br>Date: 2016-12-21
* @author Zaller.Ting zallerting@gmail.com
* @version 1.0
* 微信/Wechat: ZALLER-TING
* QQ: 851509660
* Location:Kunshan
* 实现输入(待截取字串,开始截取字节索引,截取字节长度)后,输出截取字节长度子串,不出现半个中文字符(?)
*/
public class CutStringByByte {
// 表示开始截取字节索引,首字符索引,字串最大长度,字串最大字节长度,子串长度,子串字节长度,前部分截取字节长度,截取字节长度,半个中文字符数量,临时变量
protected static int startByteIndex, firstStrIndex, maxStrLen, maxByteLen, subLen, subByteLen, beforeCutByteLen, cutByteLen, halfHanNum, tmp;
// 表示键盘输入的一行数据,待截取字串,截取子串变量
protected static String inputStr, beCutStr, subStr;
// 表示键盘输入的单个字符变量
protected static char ch;
// 表示键盘输入的一行数据组成的数组
protected static String[] inputStrArr;
// 表示以GBK编码方式解析的字节数组
protected static byte bytesByGBK[];
// 判断截取字节索引及截取字节长度是否在有效范围
protected static boolean isProperIndex, isProperLen;
// 判断是否为数值型字符串的方法(正数)
protected static boolean isNumbericStr(String inputStr) {
for(int i = 0; i < inputStr.length(); i++) {
// 返回指定索引处的字符
ch = inputStr.charAt(i);
if(ch < 46 || ch > 57) {
return false;
}
}
return true;
}
// 判断是否为数值型字符串的方法(负数)
protected static boolean isNegativeStr(String inputStr) {
ch = inputStr.charAt(0);
if(ch == '-') {
return true;
}
return false;
}
// 统计半个中文字符的数量
protected static int halfHanNum(int startByteIndex) {
// 初始化halfHanNum变量
halfHanNum = 0;
for(int i = 0; i <= startByteIndex; i++) {
// 字节索引对应值小于0时halfHanNum加1
if(bytesByGBK[i] < 0) {
++halfHanNum;
}
}
return halfHanNum;
}
// 找出需要截取子串第1个字符索引
protected static int find1stStrIndex(int startByteIndex, String subStr) {
// 统计半个中文字符的数量
halfHanNum(startByteIndex);
// startByteIndex字节索引对应字符为非中文单字节字符, 取subStr最后1个字符
if(bytesByGBK[startByteIndex] > 0) {
firstStrIndex = subStr.length() > 0 ? subStr.length() - 1 : 0;
// startByteIndex字节索引为中文字符第1个字节, 取subStr后面1个字符
} else if(halfHanNum % 2 == 1){
firstStrIndex = subStr.length();
// startByteIndex字节索引为中文字符第2个字节, 取subStr后面1个字符
} else if(halfHanNum % 2 == 0){
firstStrIndex = subStr.length();
}
return firstStrIndex;
}
// 从指定字节索引startByteIndex截取cutByteLen长度的子串方法
public static void subStr(String beCutStr, int startByteIndex, int cutByteLen) throws IOException {
/**
* 分两部分计算:
* 一.截取从索引startByteIndex开始的maxStrLen长度的子串:
* 1.截取从索引0开始的startByteIndex+1长度的子串;
* 2.找出需要截取子串的第1个字符索引firstStrIndex;
* 3.截取从索引firstStrIndex开始的maxStrLen长度的子串;
*
* 二.截取从索引startByteIndex开始的cutByteLen长度的子串:
* 1.重新计算需要截取字串最大长度maxStrLen;
* 2.截取从索引firstStrIndex开始的cutByteLen长度的子串;
* 3.返回从startByteIndex字节索引截取cutByteLen长度的子串subStr;
*/
/**
* 第一部分:截取从索引startByteIndex开始的maxStrLen长度的子串
*/
// 字串最大长度
maxStrLen = beCutStr.length();
// 字串最大字节长度
maxByteLen = beCutStr.getBytes().length;
// 前一部分截取字节长度
beforeCutByteLen = startByteIndex > 0 ? startByteIndex + 1 : 0;
// 从索引[0]截取长度[beforeCutByteLen]的子串
subStr = beCutStr.substring(0, beforeCutByteLen > maxStrLen ? maxStrLen : beforeCutByteLen);
// 子串字节长度
subByteLen = subStr.getBytes("GBK").length;
// 子串字节长度赋给临时变量tmp
tmp = subByteLen;
// 前部分截取字节长度小于子串字节长度时
while(beforeCutByteLen < subByteLen) {
// 临时变量减1
--tmp;
subStr = beCutStr.substring(0, tmp > maxStrLen ? maxStrLen : tmp);
subByteLen = subStr.getBytes("GBK").length;
}
// 找出需要截取子串第1个字符索引
find1stStrIndex(startByteIndex, subStr);
// 找出需要截取子串
subStr = beCutStr.substring(firstStrIndex, maxStrLen);
/**
* 第二部分:截取从索引startByteIndex开始的cutByteLen长度的子串
*/
// 子串字节长度
subByteLen = subStr.getBytes("GBK").length;
// 重新计算需要截取字串最大长度
maxStrLen = maxStrLen - firstStrIndex;
// 子串字节长度赋给临时变量tmp
tmp = subByteLen;
// 需要截取字节长度小于子串字节长度时
while(cutByteLen < subByteLen) {
// 需要截取字节长度减1
--tmp;
subStr = subStr.substring(0, tmp > maxStrLen ? maxStrLen : tmp);
subByteLen = subStr.getBytes("GBK").length;
}
System.out.println("“" + beCutStr + "” 从第" + startByteIndex + "字节索引截取" + cutByteLen + "字节的子串为: " + subStr + "\n");
}
// 主方法,程序的入口
public static void main(String[] args) throws IOException {
System.out.println("【本软件实现从指定字节索引截取指定字节长度子串的功能】\n");
System.out.print(" 以【待截字串,开始截取字节索引,截取字节长度】格式输入 :");
// 获取键盘输入字符串
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while((inputStr = br.readLine()) != null) {
// 通过英文逗号分隔键盘输入的字符串
inputStrArr = inputStr.split(",");
// 将键盘输入的第1个参数以"GBK"编码形式译码成1个字节数组
bytesByGBK = inputStrArr[0].getBytes("GBK");
// 判断是否键盘输入包含英文逗号且以逗号分隔的字符串中第1个不为null
if(inputStr.contains(",") && !inputStr.contains(",") && inputStrArr[0] != null) {
// 判断是否键盘输入第2个及第3个均为数值型字符串
if(isNumbericStr(inputStrArr[1]) && isNumbericStr(inputStrArr[2])) {
// 转换数值型字符串为对应数值
startByteIndex = Integer.parseInt(inputStrArr[1]);
cutByteLen = Integer.parseInt(inputStrArr[2]);
// 判断键盘输入的第2个及第3个数值是否在合理范围内
isProperIndex = startByteIndex >= 0 && startByteIndex <= bytesByGBK.length ? true : false;
isProperLen = cutByteLen >= 0 && cutByteLen <= bytesByGBK.length - startByteIndex ? true : false;
// 再判断截取字串字节索引及字节长度是否正确
if(isProperIndex) {
if(isProperLen) {
// 从指定索引位置截取指定字节长度的子串
subStr(inputStrArr[0], startByteIndex, cutByteLen);
} else {
System.out.println("截取字节长度输入有误!");
}
} else {
System.out.println("开始截取字节索引输入有误!");
}
// 判断是否键盘输入第2个及第3个均为负数值型字符串
} else if(isNegativeStr(inputStrArr[1]) && isNegativeStr(inputStrArr[2])){
System.out.println("开始截取字节索引及截取字节长度均输入有误!");
} else if(isNegativeStr(inputStrArr[1]) && !isNegativeStr(inputStrArr[2])){
System.out.println("开始截取字节索引输入有误!");
} else if(!isNegativeStr(inputStrArr[1]) && isNegativeStr(inputStrArr[2])){
System.out.println("截取字节长度输入有误!");
}
// 判断是否键盘输入包含中文逗号
} else if(inputStr.contains(",")) {
System.out.println("请以英文逗号分隔字串、字节索引、字节长度!");
} else {
System.out.println("待截取字串输入为空!");
}
System.out.print(" 以【待截字串,开始截取字节索引,截取字节长度】格式输入 :");
}
}
}