打印和写入文件时的数据不同

时间:2015-05-07 00:47:25

标签: java file-io

从服务器发送数据流。我需要将此字节流存储到文件中。问题是我输出到控制台的数据和我存储在文件中的数据是不同的。当我存储在文件中时,似乎数据格式发生了变化。

以下是该计划:

try
{
    System.out.println("My Address is "+serverSocket.getLocalSocketAddress());
    Socket server = serverSocket.accept();      // return a new socket
    System.out.println("Connected to client "+server.getRemoteSocketAddress());
    inputStream = server.getInputStream();
    in = new DataInputStream(inputStream);
    out = new FileOutputStream("output.txt");
    ArrayList<Byte> bytes = new ArrayList<Byte>();

    int curi;
    byte cur;
    byte[] curBytes = null;
    int length = 0;
    System.out.println("Before while loop");
    while((curi = in.read())!=-1 && count!=500)
    {
        System.out.println(count+" Reading some data");
        //out.write(curi);
        cur = (byte)curi;
        bytes.add(cur);
        curBytes = getPrimativeArray(bytes);

        String curBytesString = new String(curBytes, "UTF-8");
        count++;
    }
    int i=0;
    for(byte b : bytes)
    {
        System.out.print(b+"  ");
        curBytes[i] = b;
        i++;
    }
    out.write(curBytes);

    server.close();
}
catch(IOException e)
{
    e.printStackTrace();
}

我使用 System.out.print(b +&#34;&#34;); 打印的内容以及我在 curBytes [] 中存储的内容是一样。但是当我比较控制台和文件输出时,它们是不同的。

控制台输出: 0 0 113 -100 -126 -54 0 32 14 1 0 0 1 -58 60 54 0 3 63 -2 85 74 -81 -88 0 9 1 24 85 74 -81 -48 0 13 65 -113 85 74 -81 -88 0 12 125 -126 85 74 -81 -88 0 13 21 97 85 74 -81 -88 0 13 31 19 85 74 -81 -48 0 13 42 24 0 6 0 0 0 0 0 0 0 0 0 0 32 0 7 -100 0 -5 6 -128 0 -56 29 -127 23 112 -1 -1 0 0 64 0 1 -121 28 115 105 112 58 43 49 52 50 50 50 48 57 57 57 49 53 64 111 110 101 46 97 116 116 46 110 101 116 28 115 105 112 58 43 49 52 50 50 50 48 57 57 57 54 53 64 111 110 101 46 97 116 116 46 110 101 116 37 50 57 54 53 45 49 53 48 53 48 54 50 51 50 55 48 50 45 50 48 53 48 54 54 50 55 54 54 64 48 48 55 56 48 48 49 49 16 32 1 5 6 64 0 0 0 32 16 0 0 0 120 0 17 16 32 1 24 -112 16 1 46 2 0 0 0 0 0 0 0 6 1 -113 0 4 0 33 -64 -42 0 91 5 8 0 9 0 -56 0 0 0 15 3 85 74 -81 -88 0 12 -120 -28 8 0 9 0 -56 0 0 0 15 3 85 74 -81 -88 0 12 -44 -39 8 0 4 0 -56 0 0 1 11 3 85 74 -81 -88 0 9 1 24 8 0 5 0 0 0 0 0 0 3 85 74 -81 -88 0 13 31 19 8 0 1 0 -56 0 0 0 6 3 85 74 -81 -48 0 13 42 24 -64 34 4 24 9 89 83 73 80 47 50 46 48 47 84 67 80 32 91 50 48 48 49 58 53 48 54 58 52 48 48 48 58 48 58 50 48 49 48 58 48 58 55 56 58 49 49 93 58 49 51 55 48 59 98 114 97 110 99 104 61 122 57 104 71 52 98 75 50 57 48 45 48 48 55 56 48 48 49 49 45 48 48 48 102 45 52 52 49 57 55 49 52 48 51 3 85 74 -81 -88 0 12 -120 -28 127 83 73 80 47 50 46 48 47 84 67 80 32 91 50 48 48 49 58 53 48 54 58 52 48 48 48 58 48 58 50 48 49 48 58 48 58 55 56 58 49 49 93 58 49 51 55 48 59 114 101 99 101 105 118 101 100 61 50 48 48 49

文件输出: ^@^@q<9c><82>Ê^@ ^N^A^@^@^AÆ<6^@^C?þUJ¯¨^@ ^A^XUJ¯Ð^@^MA<8f>UJ¯¨^@^L}<82>UJ¯¨^@^M^UaUJ¯¨^@^M^_^SUJ¯Ð^@^M*^X^@^F^@^@^@^@^@^@^@^@^@^@ ^@^G<9c>^@û^F<80>^@È^]<81>^Wpÿÿ^@^@@^@^A<87>^\sip:+14222099915@one.att.net^\sip:+14222099965@one.att.net%2965-150506232702-2050662766@00780011^P ^A^E^F@^@^@^@ ^P^@^@^@x^@^Q^P ^A^X<90>^P^A.^B^@^@^@^@^@^@^@^F^A<8f>^@^D^@!ÀÖ^@[^E^H^@ ^@È^@^@^@^O^CUJ¯¨^@^L<88>ä^H^@ ^@È^@^@^@^O^CUJ¯¨^@^LÔÙ^H^@^D^@È^@^@^A^K^CUJ¯¨^@ ^A^X^H^@^E^@^@^@^@^@^@^CUJ¯¨^@^M^_^S^H^@^A^@È^@^@^@^F^CUJ¯Ð^@^M*^XÀ"^D^X YSIP/2.0/TCP [2001:506:4000:0:2010:0:78:11]:1370;branch=z9hG4bK290-00780011-000f-441971403^CUJ¯¨^@^L<88>ä^?SIP/2.0/TCP [2001:506:4000:0:2010:0:78:11]:1370;received=2001

请告诉我我犯了什么错误。

4 个答案:

答案 0 :(得分:2)

此处的其他答案告诉您使用PrintWriterFileWriter代替FileOutputStream,但我确信这是你想要什么。

您的问题是您将原始字节写入文件,然后将其作为字符读回,并将其与表示为字符的字节值进行比较,然后使用System.out打印。

让我们来看看打印一个值为65(或二进制为01000001)的字节时会发生什么。

当您使用System.out.print时,您将使用65的整数值调用PrintStream.print(int),这会将字符65打印到终端

当您使用out.write时,您将调用FileOutputStream.write(byte[]),它会将位01000001写入文件。

稍后,当您检查文件的内容时,您的工具将尝试将此字节解释为字符,并且很可能会使用ASCII encoding来执行此操作(即使您使用Unicode作为字符你的默认编码很可能会发生这种情况,因为Unicode是ASCII的超集。这会导致打印字符A

如果要以与System.out.print打印的方式类似的方式查看输出文件,可以在linux上使用以下命令:

$ hexdump -e '/1 "%i "' <file>

示例:

$ cat /etc/issue
Ubuntu 12.04.5 LTS \n \l
$ hexdump -e '/1 "%i "' /etc/issue
85 98 117 110 116 117 32 49 50 46 48 52 46 53 32 76 84 83 32 92 110 32
92 108 10 *

答案 1 :(得分:1)

我的第一个答案是错误的,所以我正在编辑这个,因为我假设你可以写一个字符串给FileOutputStream,但我不认为是这种情况。 FileOutputStream仅用于字节流,因此在写出文件时必须坚持使用该格式。

如果将数据保存在缓冲区[array]中,然后将这些字节写入使用输出流创建的文件,则应该可以正常工作。我发现这个文档可能会有所帮助。

主要思想是在代码中的某处,字节数组没有正确写入文件。也许只是添加close()方法。

out.close();
server.close();

reading and writing files in java

以下是我认为有用的部分。

import java.io.*;
public class Test {
public static void main(String [] args) {

    // The name of the file to create.
    String fileName = "temp.txt";

    try {
        // Put some bytes in a buffer so we can
        // write them. Usually this would be
        // image data or something. Or it might
        // be unicode text.
        String bytes = "Hello theren";
        byte[] buffer = bytes.getBytes();

        FileOutputStream outputStream =
            new FileOutputStream(fileName);

        // write() writes as many bytes from the buffer
        // as the length of the buffer. You can also
        // use
        // write(buffer, offset, length)
        // if you want to write a specific number of
        // bytes, or only part of the buffer.
        outputStream.write(buffer);

        // Always close files.
        outputStream.close();       

        System.out.println("Wrote " + buffer.length + 
            " bytes");
    }
    catch(IOException ex) {
        System.out.println(
            "Error writing file '"
            + fileName + "'");
        // Or we could just do this:
        // ex.printStackTrace();
    }
}
}

答案 2 :(得分:0)

控制台(System.out)是PrintWriter,而文件输出是FileOutputStream

StreamWriter之间的基本区别: Streams 应该操纵“原始数据”,例如直接从二进制格式获取的数字,而编写者< / strong>用于操纵“人类可读数据”,转换您编写的所有数据。

例如,6 int与6字符不同。使用流时,直接写入int,而使用writer时,数据wrriten将转换为字符。

然后,如果您希望文件输出与控制台输出相同,请不要使用FileOutputStream,而应使用FileWriter,方法write(String)

如何使这项工作:

1 - 将out = new FileOutputStream("output.txt");替换为out = new FileWriter("output.txt");

2 - 将out.write(curBytes);替换为:

for (byte b : curBytes) {
  out.write(b + " ");
}

答案 3 :(得分:-1)

我建议您使用IOUtils.copy并使用BufferedReader 包装你的InputStream。
输出流显然应该是FileOutputStream

我希望这有帮助