打印和写入文件时的不同数据
Different data when printing and writing to file
有从服务器发送的数据流。我需要将这个字节流存储到一个文件中。问题是我输出到控制台的数据和我存储在文件中的数据不同。当我存储在文件中时,数据格式似乎发生了变化。
程序如下:
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+" "); 打印的内容和我存储在 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
请让我知道我在哪一步出错了。
控制台(System.out
)是一个PrintWriter
,而文件输出是一个FileOutputStream
。
Stream
和 Writer
之间的基本区别:Streams 应该操纵 "raw data",就像直接从二进制格式中获取数字一样,而 writers 用于操作 "human-readable data",转换您写入的所有数据。
例如,6
int 不同于 6
字符。当你使用流时,你直接写入 int,而使用 writer 时,写入的数据将转换为字符。
然后,如果您希望文件输出与控制台输出相同,请不要使用 FileOutputStream
,而是使用 FileWriter, and it's method write(String).
如何进行这项工作:
1 - 将 out = new FileOutputStream("output.txt");
替换为 out = new FileWriter("output.txt");
2 - 将 out.write(curBytes);
替换为:
for (byte b : curBytes) {
out.write(b + " ");
}
我建议你使用 IOUtils.copy and use a BufferedReader
包装你的 InputStream。
输出流显然应该是 FileOutputStream
希望对您有所帮助
这里的其他答案告诉您使用 PrintWriter
或 FileWriter
而不是 FileOutputStream
但我很确定这 不是 你想要什么。
您的问题是您正在将原始字节写入文件,然后将其作为字符读回并将其与表示为字符的字节值进行比较,然后用 System.out
.
打印
让我们看一下打印值为 65
(或二进制 01000001
)的字节时会发生什么。
当您使用 System.out.print
时,您将使用 65
的整数值调用 PrintStream.print(int)
,这将依次打印字符 6
和 5
到终端。
当您使用 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 *
我的第一个答案是错误的,所以我正在编辑它,因为我假设您可以向 FileOutputStream 写出一个字符串,但我认为情况并非如此。 FileOutputStream 仅用于字节流,因此在写入文件时必须坚持该格式。
如果您将数据保存在缓冲区[数组] 中,然后将这些字节写入您使用输出流创建的文件,它应该可以工作。我发现这篇文档可能会有帮助。
主要思想是您的代码中某处未将字节数组正确写入文件。也许这只是添加 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();
}
}
}
有从服务器发送的数据流。我需要将这个字节流存储到一个文件中。问题是我输出到控制台的数据和我存储在文件中的数据不同。当我存储在文件中时,数据格式似乎发生了变化。
程序如下:
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+" "); 打印的内容和我存储在 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
请让我知道我在哪一步出错了。
控制台(System.out
)是一个PrintWriter
,而文件输出是一个FileOutputStream
。
Stream
和 Writer
之间的基本区别:Streams 应该操纵 "raw data",就像直接从二进制格式中获取数字一样,而 writers 用于操作 "human-readable data",转换您写入的所有数据。
例如,6
int 不同于 6
字符。当你使用流时,你直接写入 int,而使用 writer 时,写入的数据将转换为字符。
然后,如果您希望文件输出与控制台输出相同,请不要使用 FileOutputStream
,而是使用 FileWriter, and it's method write(String).
如何进行这项工作:
1 - 将 out = new FileOutputStream("output.txt");
替换为 out = new FileWriter("output.txt");
2 - 将 out.write(curBytes);
替换为:
for (byte b : curBytes) {
out.write(b + " ");
}
我建议你使用 IOUtils.copy and use a BufferedReader
包装你的 InputStream。
输出流显然应该是 FileOutputStream
希望对您有所帮助
这里的其他答案告诉您使用 PrintWriter
或 FileWriter
而不是 FileOutputStream
但我很确定这 不是 你想要什么。
您的问题是您正在将原始字节写入文件,然后将其作为字符读回并将其与表示为字符的字节值进行比较,然后用 System.out
.
让我们看一下打印值为 65
(或二进制 01000001
)的字节时会发生什么。
当您使用 System.out.print
时,您将使用 65
的整数值调用 PrintStream.print(int)
,这将依次打印字符 6
和 5
到终端。
当您使用 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 *
我的第一个答案是错误的,所以我正在编辑它,因为我假设您可以向 FileOutputStream 写出一个字符串,但我认为情况并非如此。 FileOutputStream 仅用于字节流,因此在写入文件时必须坚持该格式。
如果您将数据保存在缓冲区[数组] 中,然后将这些字节写入您使用输出流创建的文件,它应该可以工作。我发现这篇文档可能会有帮助。
主要思想是您的代码中某处未将字节数组正确写入文件。也许这只是添加 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();
}
}
}