使用固定字节数java读取文件
我正在编写一个程序来复制大文件,所以我想读取特定数量的字节并写入另一个文件。我想复制文件并获得相同的字节数。但我得到更多。另外,我还希望文件的内容保持不变。我做错了什么?如果有人能解释为什么我会收到这些额外的文本,那就太好了 test.txt使用固定字节数java读取文件,java,file,byte,filestream,Java,File,Byte,Filestream,我正在编写一个程序来复制大文件,所以我想读取特定数量的字节并写入另一个文件。我想复制文件并获得相同的字节数。但我得到更多。另外,我还希望文件的内容保持不变。我做错了什么?如果有人能解释为什么我会收到这些额外的文本,那就太好了 test.txt sometext sometext sometext sometext sometext sometext sometext sometext sometext sometext sometext sometext sometext sometext so
sometext sometext sometext sometext
sometext sometext sometext sometext
sometext sometext sometext sometext
sometext sometext sometext sometext
Practice.java
public class Practice{
public static void main(String[] args){
byte[] buffer = new byte[100];
try{
FileInputStream f = new FileInputStream("test.txt");
FileWriter writer = new FileWriter("copy_test.txt");
int b;
while ((b=f.read(buffer)) != -1 )
writer.write(new String(buffer));
writer.close();
} catch(Exception e){
e.printStackTrace();
}
}
}
复制_test.txt
sometext sometext sometext sometext
sometext sometext sometext sometext
sometext sometext sometext sometext
sometext sometext sometext sometext
metext sometext sometext
sometext sometext sometext
您的代码有几个问题: 您正在使用默认平台编码,通过调用new Stringbyte[]而不是指定编码,将二进制数据转换为文本 您正在使用默认的平台编码通过FileWriter将文本写入磁盘 您正在无条件地将整个缓冲区转换为文本,即使您的读取没有填满它-您可以通过使用一个字符串构造函数重载来修复这一问题,该重载获取偏移量和字节数,并将0和b作为参数传递,尽管我不会这样做。使用try with resources语句。 您根本没有关闭输入流,如果抛出异常,您也没有关闭编写器。使用try with resources语句。 您正在捕获异常-这通常是个坏主意。如果必须,捕获特定的异常;就我个人而言,我只有很少的捕获块——一般来说,如果出现问题,中止当前的整个操作是合适的。当然,在某些情况下,您可以重试等。我理解这可能只是在这里的示例代码中,而不是在实际代码中。 如果您只是试图复制一个文件,那么根本没有理由在二进制和文本之间进行转换——请坚持使用输入流和输出流 如果您只是试图复制一个文件,那么可以使用来避免编写任何代码,假设您使用的是Java7。如果你不是,你应该是! 如果您只想将InputStream复制到OutputStream,而您没有可用的实用程序库-这是许多库的一部分,您可以使用以下工具:
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = input.read(buffer)) != -1) {
output.write(buffer, 0, bytesRead);
}
您的代码有几个问题: 您正在使用默认平台编码,通过调用new Stringbyte[]而不是指定编码,将二进制数据转换为文本 您正在使用默认的平台编码通过FileWriter将文本写入磁盘 您正在无条件地将整个缓冲区转换为文本,即使您的读取没有填满它-您可以通过使用一个字符串构造函数重载来修复这一问题,该重载获取偏移量和字节数,并将0和b作为参数传递,尽管我不会这样做。使用try with resources语句。 您根本没有关闭输入流,如果抛出异常,您也没有关闭编写器。使用try with resources语句。 您正在捕获异常-这通常是个坏主意。如果必须,捕获特定的异常;就我个人而言,我只有很少的捕获块——一般来说,如果出现问题,中止当前的整个操作是合适的。当然,在某些情况下,您可以重试等。我理解这可能只是在这里的示例代码中,而不是在实际代码中。 如果您只是试图复制一个文件,那么根本没有理由在二进制和文本之间进行转换——请坚持使用输入流和输出流 如果您只是试图复制一个文件,那么可以使用来避免编写任何代码,假设您使用的是Java7。如果你不是,你应该是! 如果您只想将InputStream复制到OutputStream,而您没有可用的实用程序库-这是许多库的一部分,您可以使用以下工具:
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = input.read(buffer)) != -1) {
output.write(buffer, 0, bytesRead);
}
为什么缓冲区大小为1024?@user3834119:为什么不?虽然流中也可能存在缓冲,但它感觉像是内存使用和过多IO之间的合理平衡。这是一个有点任意的数字——当然,和你的100一样。@jonsket文件库使用8kb——也许1kb有点小。虽然对于一个小文件来说,它很可能完全没有区别。1kib太小了,真的。当今大多数现代体系结构上的页面粒度为8kiB。@fge-页面粒度与此没有直接关系。我们在这里谈论的是文件。使用太小的缓冲区执行读/写操作的问题是执行系统调用和上下文切换时的开销。是的,1kb可能太小了。为什么缓冲区的大小是1024?@user3834119:为什么不呢?虽然流中也可能存在缓冲,但它感觉像是内存使用和过多IO之间的合理平衡。这是一个有点任意的数字——当然,和你的100一样。@jonsket文件库使用8kb——也许1kb有点小。虽然对于一个小文件来说,它很可能完全没有区别。1kib太小了,真的。当今大多数现代体系结构上的页面粒度为8kiB。@fge-页面粒度与此没有直接关系。我们在这里谈论的是文件。使用缓冲区执行读/写操作的问题
太小的开销是系统调用和上下文切换的开销。但是是的,1kb可能太小了。呃,为什么不直接使用呢?另外,您使用InputStream作为源,使用Writer作为目标?嗯?基本上你在读苹果,但在写橘子。@fge因为它;这只是一个示例代码,实际上我正在将文件从服务器传输到客户端。因此,我无法使用Files.copy。取决于服务器。file API允许文件系统覆盖任何内容。例如。请注意。呃,为什么不直接使用?另外,您使用InputStream作为源,使用Writer作为目标?嗯?基本上你在读苹果,但在写橘子。@fge因为它;这只是一个示例代码,实际上我正在将文件从服务器传输到客户端。因此,我无法使用Files.copy。取决于服务器。file API允许文件系统覆盖任何内容。例如。请注意这一点。