Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.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字节流非英语字符_Java_Java Io - Fatal编程技术网

Java字节流非英语字符

Java字节流非英语字符,java,java-io,Java,Java Io,我读了这个。作为xanadu.txt内容,请使用“测试”。文件大小为4个字节。如果我使用debug运行out.write(c)1个字节,每次打开文件outreach.txt(带记事本)后,我会依次看到:t-->te-->tes-->test。好啊 但是,如果我们将源文件(xanadu.txt)的内容更改为希腊语(或其他语言),相当于test(τέστ),那么该文件现在有8个字节大小(我认为,因为UTF每个字符有2个字节)。当再次调试时,每次输出时,它都会出现无意义的象形字符。write(c)运行

我读了这个。作为xanadu.txt内容,请使用“测试”。文件大小为4个字节。如果我使用debug运行
out.write(c)
1个字节,每次打开文件outreach.txt(带记事本)后,我会依次看到:t-->te-->tes-->test。好啊
但是,如果我们将源文件(xanadu.txt)的内容更改为希腊语(或其他语言),相当于test(τέστ),那么该文件现在有8个字节大小(我认为,因为UTF每个字符有2个字节)。当再次调试时,每次
输出时,它都会出现无意义的象形字符。write(c)
运行。当最后一个字节(第8个)打印出来时,原来的希腊字(τστ)突然出现。为什么?如果我们选择控制台流作为目标(在netbeans中)也是一样的,但在这种情况下,如果调试,奇怪的字符会保留在末尾,但如果我们正常运行它(!!!)。

正如您所观察到的,单个字符(Java内部表示中的16位)会变成字节流表示中的可变字节数,特别是UTF-8

(有些字符占用两个char值;我将忽略这些值,但答案仍然适用,只是更多)

如果您在实验中输出“字节方式”,在某些情况下,您将输出一个小数字符。这是一个毫无意义的非法序列;然而,一些软件(如记事本)会试图理解它。这甚至可能包括猜测编码。例如,我不知道是这样的,但是如果文件在其前几个字节中不是有效的UTF-8,并且我们知道您的半个字符输出不是有效的UTF-8,那么记事本可能会猜测一种完全不同的编码,它会将字节序列视为完全不同字符的有效表示


tl;dr-垃圾输出,垃圾显示。

现代计算机有一个巨大的表格,里面有40亿个字符。每个字符由一个32位数字标识。你能想到的所有角色都在这里;从基本的“测试”到“τστ”再到雪人(☃ ), 对于表示右向左拼写单词的特殊不可见的词即将出现,到一组结词(例如,代表FF结扎的单个字符),表情符号、颜色和全部:TL;DR。 阅读:

不要按字节分析文本文件。请使用专门为处理文本而构建的类。例如,使用及其方法

细节 请注意,在警告的底部,这不是处理文本文件的正确方法:

CopyBytes看起来像一个普通的程序,但实际上它代表了一种应该避免的低级I/O。由于xanadu.txt包含字符数据,最好的方法是使用字符流,如下一节所述

文本文件可能使用也可能不使用单个八位字节来表示单个字符,例如文件。您的示例代码假定每个字符有一个八位字节,用于
测试
作为内容,但不用于
τστ
作为内容

作为一名程序员,您必须从数据文件的发布者那里知道在编写表示原始文本的数据时使用了什么编码。通常,在编写文本时最好使用编码

编写一个包含两行的文本文件:

试验 τστ

…并使用编码为的进行保存

将该文件作为对象集合读取

UTF-16与UTF-8 你说:

我想因为UTF,我们每个字符有2个字节)

没有“UTF”这样的东西

  • 编码每个字符使用一对或多对八位字节
  • 编码每个字符使用1、2、3或4个八位字节
可以使用编码、UTF-16或UTF-8将
τστ
等文本内容写入文件。请注意,UTF-8目前通常是首选的。请注意,UTF-8是US-ASCII的超集,因此任何US-ASCII文件也是UTF-8文件

字符作为代码点 如果要对文本中的每个字符进行示例,请将它们视为数字

切勿在Java中使用
char
类型。该类型甚至无法表示中定义的一半字符,现在已过时

我们可以通过添加这两行代码来查询上面示例文件中的每个字符

IntStream codePoints = line.codePoints();
codePoints.forEach( System.out :: println );
像这样:

Path path = Paths.get( "/Users/basilbourque/some_text.txt" );
try
{
    List < String > lines = Files.readAllLines( path , StandardCharsets.UTF_8 );
    for ( String line : lines )
    {
        System.out.println( "line = " + line );
        IntStream codePoints = line.codePoints();
        codePoints.forEach( System.out :: println );
    }
}
catch ( IOException e )
{
    e.printStackTrace();
}
如果您还不熟悉流,例如
整数
对象的
列表

Path path = Paths.get( "/Users/basilbourque/some_text.txt" );
try
{
    List < String > lines = Files.readAllLines( path , StandardCharsets.UTF_8 );
    for ( String line : lines )
    {
        System.out.println( "line = " + line );
    }
}
catch ( IOException e )
{
    e.printStackTrace();
}
Path path = Paths.get( "/Users/basilbourque/some_text.txt" );
try
{
    List < String > lines = Files.readAllLines( path , StandardCharsets.UTF_8 );
    for ( String line : lines )
    {
        System.out.println( "line = " + line );
        List < Integer > codePoints = line.codePoints().boxed().collect( Collectors.toList() );
        for ( Integer codePoint : codePoints )
        {
            System.out.println( "codePoint = " + codePoint );
        }
    }
}
catch ( IOException e )
{
    e.printStackTrace();
}
给定一个代码点编号,我们可以

字符串s=字符。toString(941);//έ性格


请注意,某些文本字符可能表示为多个代码点,例如带有变音符号的字母。(文本处理不是一件简单的事情。)

您是否尝试过将字节流转换为字符串,然后使用string.charAt()方法从字符串中获取每个字符?@knvb原则上,问题不会以这种方式解决。例如,由单个表情符号组成的
字符串的
length()
可能等于
2
,因此
charAt
不是一个通用的答案。我尝试了以下代码,它是有效的。公共类MyClass{public static void main(String args[]){String data=“τέστ”;for(int i=0;i“它在这种特定情况下工作”通常是一个糟糕的答案,除非给出更多的上下文和解释。据我所知,Stackoverflow只针对NASA和CERN研究人员提出的最巧妙的问题!!!!很好。最后一个问题。我如何在目标文件中打印每个字节的数量而不是字符?因为我们讨论的是原始字节streams,因为c表示1到256之间的字节,所以我希望是out。如果我们不指定一些编码来根据编码转换这些序列,write(c)将打印每个字节的编号。@非线性out.write()被指定为写入一个字节。而不是一堆ASCII字符来表示该字节(这,嘿,让我们回到编码上来!现在你