Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将Java字符串拆分为1024字节的块_Java_String_Split_Byte - Fatal编程技术网

将Java字符串拆分为1024字节的块

将Java字符串拆分为1024字节的块,java,string,split,byte,Java,String,Split,Byte,在java中,什么是将字符串拆分为1024字节块的有效方法? 如果有多个区块,则需要在所有后续区块中重复标题(固定大小的字符串)。有两种方法,快速和内存保守方法。但首先,您需要知道字符串中包含哪些字符。ASCII码?是否存在UMLAUT(字符数介于128和255之间)甚至Unicode(s.getChar()返回大于256的内容)。根据这一点,您将需要使用不同的编码。如果您有二进制数据,请尝试“iso-8859-1”,因为它将保留字符串中的数据。如果您使用Unicode,请尝试“utf-8”。我

在java中,什么是将字符串拆分为1024字节块的有效方法?
如果有多个区块,则需要在所有后续区块中重复标题(固定大小的字符串)。

有两种方法,快速和内存保守方法。但首先,您需要知道字符串中包含哪些字符。ASCII码?是否存在UMLAUT(字符数介于128和255之间)甚至Unicode(s.getChar()返回大于256的内容)。根据这一点,您将需要使用不同的编码。如果您有二进制数据,请尝试“iso-8859-1”,因为它将保留字符串中的数据。如果您使用Unicode,请尝试“utf-8”。我假设二进制数据:

String encoding = "iso-8859-1";
最快的方式:

ByteArrayInputStream in = new ByteArrayInputStream (string.getBytes(encoding));
请注意,字符串是Unicode,因此每个字符都需要两个字节。您必须指定编码(不要依赖“平台默认值”。这只会在以后引起痛苦)

现在,您可以使用

byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) > 0) { ... }
这需要大约三倍于原始字符串的RAM

一种更节省内存的方法是编写一个转换器,该转换器采用StringReader和OutputStreamWriter(封装ByteArrayOutputStream)。将字节从读卡器复制到写卡器,直到底层缓冲区包含一个数据块:

执行此操作时,将数据复制到实际输出(在头的前面),将附加字节(Unicode->byte转换可能已生成)复制到临时缓冲区,调用buffer.reset()并将临时缓冲区写入缓冲区

代码如下所示(未测试):

这只需要几千字节的RAM

[编辑]评论中对字符串中的二进制数据进行了长时间的讨论。首先,只要在创建二进制数据并将其存储到某个位置时小心,将其放入字符串中是完全安全的。要创建这样的字符串,请获取byte[]数组并:

String safe = new String (array, "iso-8859-1");
在Java中,ISO-8859-1(也称为ISO-Latin1)是1:1映射。这意味着数组中的字节将不会以任何方式进行解释。现在,您可以对数据使用substring()等,或者使用索引搜索数据,在数据上运行regexp等。例如,查找0字节的位置:

int pos = safe.indexOf('\u0000');
如果您不知道数据的编码,并且希望在某些编解码器弄乱数据之前查看数据,那么这一点尤其有用

要将数据写入某个位置,反向操作为:

字节[]数据=safe.getBytes(“iso-8859-1”)

切勿使用默认方法
新建字符串(数组)
String.getBytes()
有一天,您的代码将在不同的平台上执行,它将崩溃

现在是字符串中字符>255的问题。如果使用此方法,则字符串中永远不会有任何此类字符。也就是说,如果出于某种原因存在任何异常,那么getBytes()将抛出一个异常,因为无法用ISO-Latin1表示所有Unicode字符,因此代码不会以静默方式失败,这是安全的

有些人可能会争辩说,这不够安全,您不应该混合使用字节和字符串。在这个时代,我们没有那种奢侈。许多数据没有明确的编码信息(例如,文件没有“encoding”属性,因为它们具有访问权限或名称)。XML是为数不多的具有显式编码信息的格式之一,有些编辑器(如Emacs或jEdit)使用注释来指定这些重要信息。这意味着,在处理字节流时,您必须始终知道它们采用的编码方式。到目前为止,无论数据来自何处,都无法编写始终有效的代码

即使使用XML,也必须先将文件头读取为字节,以确定编码,然后才能解码肉

重要的一点是坐下来,找出生成您必须处理的数据流所使用的编码。如果你那样做,你就很好,如果你不这样做,你就注定要失败。这种混淆源于这样一个事实,即大多数人都没有意识到,根据编码的不同,同一个字节可能意味着不同的东西,甚至没有意识到存在多个编码。此外,如果Sun没有引入“平台默认编码”的概念,它也会有所帮助

初学者的要点:

  • 有多个编码(字符集)
  • 这里的字符比英语使用的要多。甚至有几种(ASCII码、全宽码、阿拉伯文-印度文、孟加拉文)
  • 您必须知道用于生成正在处理的数据的编码
  • 您必须知道应该使用哪种编码来写入正在处理的数据
  • 您必须知道指定此编码信息的正确方法,以便下一个程序能够解码您的输出(XML头、HTML元标记、特殊编码注释等等)

ASCII的时代已经过去。

字符串和字节是两个完全不同的东西,因此想要将字符串拆分为字节就像想要将一幅画拆分为韵文一样毫无意义

你到底想做什么

要在字符串和字节之间进行转换,需要指定一种编码,该编码可以对字符串中的所有字符进行编码。根据编码和字符,其中一些可能跨越多个字节

您可以将字符串拆分为1024个字符的块,并将其编码为字节,但每个块可能超过1024个字节

或者,您可以将原始字符串编码为字节,然后将其拆分为1024个字节,但在再次将整个字符串解码为字符串之前,您必须确保将其作为字节追加,否则,当一个字符跨越1个字节以上时,可能会在拆分点处出现乱码

如果在字符串可能很长的情况下担心内存使用,那么应该使用streams(java.io包)对en/进行解码和拆分,以避免将数据作为副本多次保存在内存中
int pos = safe.indexOf('\u0000');
private static String chunk_split(String original, int length, String separator) throws IOException {
    ByteArrayInputStream bis = new ByteArrayInputStream(original.getBytes());
    int n = 0;
    byte[] buffer = new byte[length];
    String result = "";
    while ((n = bis.read(buffer)) > 0) {
        for (byte b : buffer) {
            result += (char) b;
        }
        Arrays.fill(buffer, (byte) 0);
        result += separator;
    }
    return result;
}
public static void main(String[] args) throws IOException{
       String original = "abcdefghijklmnopqrstuvwxyz";
       System.out.println(chunk_split(original,5,"\n"));
}
abced
fghij
klmno
pqrst
uvwxy
z
private static ArrayList<String> chunkLogMessage(String logMessage) throws Exception {
    ArrayList<String> messages = new ArrayList<>();
    if(logMessage.getBytes().length > CHUNK_SIZE) {
        Log.e("chunk_started", System.currentTimeMillis()+"");
        byte[] buffer = new byte[CHUNK_SIZE];
        int start = 0, end = buffer.length;
        long remaining = logMessage.getBytes().length;
        ByteArrayInputStream inputStream = new ByteArrayInputStream(logMessage.getBytes());
        while ((inputStream.read(buffer, start, end)) != -1){
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            outputStream.write(buffer, start, end);
            messages.add(outputStream.toString("UTF-8"));
            remaining = remaining - end;
            if(remaining <= end){
                end = (int) remaining;
            }
        }
        Log.e("chunk_ended", System.currentTimeMillis()+"");
        return messages;
    }
    messages.add(logMessage);
    return messages;
}
22:08:00.262 3382-3425/com.sample.app E/chunk_started: 1533910080261
22:08:01.228 3382-3425/com.sample.app E/chunk_ended: 1533910081228
22:08:02.468 3382-3425/com.sample.app E/chunk_started: 1533910082468
22:08:03.478 3382-3425/com.sample.app E/chunk_ended: 1533910083478
22:09:19.801 3382-3382/com.sample.app E/chunk_started: 1533910159801
22:09:20.662 3382-3382/com.sample.app E/chunk_ended: 1533910160662

DataChunker chunker = new DataChunker(8192, blob) {
@Override 
public void chunkFound(byte[] foundChunk, int bytesProcessed) {
//process chunk here
}
@Override 
public void chunksExhausted(int bytesProcessed) { 
//called when all the blocks have been exhausted
} 
};

String blob = "Experience is wasted if history does not repeat itself...Gbemiro Jiboye";

 final StringBuilder builder = new StringBuilder();
        StringChunker chunker = new StringChunker(4, blob) {
            @Override
            public void chunkFound(String foundChunk, int bytesProcessed) {
                builder.append(foundChunk);
                System.out.println("Found: "+foundChunk+", bytesProcessed: "+bytesProcessed+" bytes");
            }

            @Override
            public void chunksExhausted(int bytesProcessed) {
                System.out.println("Processed all of: "+bytesProcessed+" bytes. Rebuilt string is: "+builder.toString());
            }
        };