想用BufferedOutputStream复制文件,结果文件编码变了,怎么回事?

时间:2022-02-24 10:07:28
class CopyFile
    {  
     boolean copy(String fileFrom, String fileTo) 
    {  
        try {  
            FileInputStream in = new FileInputStream(fileFrom);  
            FileOutputStream out = new FileOutputStream(fileTo); 
            BufferedInputStream buffi=new BufferedInputStream(in);
            BufferedOutputStream buffo=new BufferedOutputStream(out);
        
            int temp=0;
         
            while((temp=buffi.read())!=-1)
            {
                buffo.write(temp);
            }
          
            in.close();  
            out.close(); 
            
            return true;  
        } 
        catch (IOException ex) 
        {  
            return false;  
        }  
    }  
}  

复制文件,有的文件会变短了,有的提示说是变成了unicode码了,请问怎么回事?

15 个解决方案

#1


你copy传的参数是new一个文件吧

#2


不应该是路径命

#3


问题好像是因为buffi读取完的时候但是又一部分数据在buffo的内存里(默认大小4096k),需要再while循环后面加一句 buffo.flush()就好了

#4


引用 3 楼 u010918104 的回复:
问题好像是因为buffi读取完的时候但是又一部分数据在buffo的内存里(默认大小4096k),需要再while循环后面加一句 buffo.flush()就好了
还是不行啊!

#5


引用 1 楼 PanShuShuOldWang 的回复:
你copy传的参数是new一个文件吧
copy 传的是string 啊

#6


引用 4 楼 csdngameasm 的回复:
Quote: 引用 3 楼 u010918104 的回复:

问题好像是因为buffi读取完的时候但是又一部分数据在buffo的内存里(默认大小4096k),需要再while循环后面加一句 buffo.flush()就好了
还是不行啊!


package copy;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

class CopyFile {
static String s="*";
boolean copy(String fileFrom, String fileTo) {
try {
FileInputStream in = new FileInputStream(fileFrom);
FileOutputStream out = new FileOutputStream(fileTo);
BufferedInputStream buffi = new BufferedInputStream(in);
BufferedOutputStream buffo = new BufferedOutputStream(out);

int temp = 0;

while ((temp = buffi.read()) != -1) {
buffo.write(temp);
s=s+temp;
}
            buffo.flush();
in.close();
out.close();

return true;
} catch (IOException ex) {
ex.getStackTrace();
return false;
}
}
public static void main(String[] args){
CopyFile fc=new CopyFile();
if (fc.copy("in.txt", "out.txt")){
System.out.println("ok");
System.out.println(s);
}else{
System.out.println("error");
}
}

我试过10M的txt word jpg 都可以啊,什么都不少。jdk7.1

#7


引用 6 楼 u010918104 的回复:
Quote: 引用 4 楼 csdngameasm 的回复:

Quote: 引用 3 楼 u010918104 的回复:

问题好像是因为buffi读取完的时候但是又一部分数据在buffo的内存里(默认大小4096k),需要再while循环后面加一句 buffo.flush()就好了
还是不行啊!


package copy;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

class CopyFile {
static String s="*";
boolean copy(String fileFrom, String fileTo) {
try {
FileInputStream in = new FileInputStream(fileFrom);
FileOutputStream out = new FileOutputStream(fileTo);
BufferedInputStream buffi = new BufferedInputStream(in);
BufferedOutputStream buffo = new BufferedOutputStream(out);

int temp = 0;

while ((temp = buffi.read()) != -1) {
buffo.write(temp);
s=s+temp;
}
            buffo.flush();
in.close();
out.close();

return true;
} catch (IOException ex) {
ex.getStackTrace();
return false;
}
}
public static void main(String[] args){
CopyFile fc=new CopyFile();
if (fc.copy("in.txt", "out.txt")){
System.out.println("ok");
System.out.println(s);
}else{
System.out.println("error");
}
}

我试过10M的txt word jpg 都可以啊,什么都不少。jdk7.1

把System.out.println(s);
s=s+temp;
这两句去了 这两句是我用来看buffi是怎么工作的;

#8


最后的close应该关闭缓冲流
in.close
out.close
改成
buffi.close
buffo.close

#9


@csdngameasm  也可以像8楼这样 buffo.close()因为缓存流在close()的时候会自动flush()

#10


建议你参考FileChannel.transferTo(WritableChannel),一行搞定的事!

#11


引用 9 楼 u010918104 的回复:
@csdngameasm  也可以像8楼这样 buffo.close()因为缓存流在close()的时候会自动flush()
1.我用的是MacOSX笔记本,用文本文件测试的时候,会显示编码为Unicode,无法打开,所以我发现了编码被改变的问题,如果大家用的是windows,可能因为兼容做的好,没有提示,反倒发现不了问题了。2.每次复制出来的文件正好4M,不管源文件多大,正如你说的buffo是4096k缓存,是这样吗?

#12


引用 11 楼 csdngameasm 的回复:
Quote: 引用 9 楼 u010918104 的回复:

@csdngameasm  也可以像8楼这样 buffo.close()因为缓存流在close()的时候会自动flush()
1.我用的是MacOSX笔记本,用文本文件测试的时候,会显示编码为Unicode,无法打开,所以我发现了编码被改变的问题,如果大家用的是windows,可能因为兼容做的好,没有提示,反倒发现不了问题了。2.每次复制出来的文件正好4M,不管源文件多大,正如你说的buffo是4096k缓存,是这样吗?

我是WIN7的,编码的问题因为我没在mac上试过,不过我觉得既然我用这程序能复制txt word 和jpg,就是说单纯在流中的都是纯数据,至于编码和解码是io类内部的事情。从结果看复制的附件和原件是一样的。你说缓存大小这个其实是可以测试的你在new BuffOutoutStream(FlieOutputStream out,int size)就可以了。我说的这里4m是可能缺少4m的数据,但是你说你只生成4m的文件我刚刚试了下用你这段复制一个33m的东西 还是33m。这点我也挺奇怪的,要不你找个win系统试下。。。

#13


如果你觉得是编码问题的话,你可以试试用DataOutputStream输出看看,这个类是能选输出编码的格式的你可以选writeBytes()或者writeUTF()不过参数是String 需要对应使用DataInputStream,或者把输入流的数据转化成字符(有点复杂需要知道编码规则);看看结果是不是不一样

#14


你们好纠结!

package test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;

public class CopyFile{
  public static final void copy(File src,File dst) throws IOException{
    FileInputStream fis=new FileInputStream(src);
    FileChannel in=fis.getChannel();
    FileOutputStream fos=new FileOutputStream(dst);
    FileChannel out=fos.getChannel();
    in.transferTo(0,in.size(),out);
    fos.close();
    fis.close();
  }

  public static final void copy(String src,String dst) throws IOException{
    copy(new File(src),new File(dst));
  }

  public static void main(String...args) throws IOException{
    copy("...","...");
  }
}

#15


引用 13 楼 u010918104 的回复:
如果你觉得是编码问题的话,你可以试试用DataOutputStream输出看看,这个类是能选输出编码的格式的你可以选writeBytes()或者writeUTF()不过参数是String 需要对应使用DataInputStream,或者把输入流的数据转化成字符(有点复杂需要知道编码规则);看看结果是不是不一样


引用 14 楼 zoeg 的回复:
你们好纠结!

package test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;

public class CopyFile{
  public static final void copy(File src,File dst) throws IOException{
    FileInputStream fis=new FileInputStream(src);
    FileChannel in=fis.getChannel();
    FileOutputStream fos=new FileOutputStream(dst);
    FileChannel out=fos.getChannel();
    in.transferTo(0,in.size(),out);
    fos.close();
    fis.close();
  }

  public static final void copy(String src,String dst) throws IOException{
    copy(new File(src),new File(dst));
  }

  public static void main(String...args) throws IOException{
    copy("...","...");
  }
}


好的,我再试试,非常谢谢两位相助,初来论坛,诸多不懂,没有找到给分选项,抱歉,等我找到会把分给两位。

#1


你copy传的参数是new一个文件吧

#2


不应该是路径命

#3


问题好像是因为buffi读取完的时候但是又一部分数据在buffo的内存里(默认大小4096k),需要再while循环后面加一句 buffo.flush()就好了

#4


引用 3 楼 u010918104 的回复:
问题好像是因为buffi读取完的时候但是又一部分数据在buffo的内存里(默认大小4096k),需要再while循环后面加一句 buffo.flush()就好了
还是不行啊!

#5


引用 1 楼 PanShuShuOldWang 的回复:
你copy传的参数是new一个文件吧
copy 传的是string 啊

#6


引用 4 楼 csdngameasm 的回复:
Quote: 引用 3 楼 u010918104 的回复:

问题好像是因为buffi读取完的时候但是又一部分数据在buffo的内存里(默认大小4096k),需要再while循环后面加一句 buffo.flush()就好了
还是不行啊!


package copy;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

class CopyFile {
static String s="*";
boolean copy(String fileFrom, String fileTo) {
try {
FileInputStream in = new FileInputStream(fileFrom);
FileOutputStream out = new FileOutputStream(fileTo);
BufferedInputStream buffi = new BufferedInputStream(in);
BufferedOutputStream buffo = new BufferedOutputStream(out);

int temp = 0;

while ((temp = buffi.read()) != -1) {
buffo.write(temp);
s=s+temp;
}
            buffo.flush();
in.close();
out.close();

return true;
} catch (IOException ex) {
ex.getStackTrace();
return false;
}
}
public static void main(String[] args){
CopyFile fc=new CopyFile();
if (fc.copy("in.txt", "out.txt")){
System.out.println("ok");
System.out.println(s);
}else{
System.out.println("error");
}
}

我试过10M的txt word jpg 都可以啊,什么都不少。jdk7.1

#7


引用 6 楼 u010918104 的回复:
Quote: 引用 4 楼 csdngameasm 的回复:

Quote: 引用 3 楼 u010918104 的回复:

问题好像是因为buffi读取完的时候但是又一部分数据在buffo的内存里(默认大小4096k),需要再while循环后面加一句 buffo.flush()就好了
还是不行啊!


package copy;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

class CopyFile {
static String s="*";
boolean copy(String fileFrom, String fileTo) {
try {
FileInputStream in = new FileInputStream(fileFrom);
FileOutputStream out = new FileOutputStream(fileTo);
BufferedInputStream buffi = new BufferedInputStream(in);
BufferedOutputStream buffo = new BufferedOutputStream(out);

int temp = 0;

while ((temp = buffi.read()) != -1) {
buffo.write(temp);
s=s+temp;
}
            buffo.flush();
in.close();
out.close();

return true;
} catch (IOException ex) {
ex.getStackTrace();
return false;
}
}
public static void main(String[] args){
CopyFile fc=new CopyFile();
if (fc.copy("in.txt", "out.txt")){
System.out.println("ok");
System.out.println(s);
}else{
System.out.println("error");
}
}

我试过10M的txt word jpg 都可以啊,什么都不少。jdk7.1

把System.out.println(s);
s=s+temp;
这两句去了 这两句是我用来看buffi是怎么工作的;

#8


最后的close应该关闭缓冲流
in.close
out.close
改成
buffi.close
buffo.close

#9


@csdngameasm  也可以像8楼这样 buffo.close()因为缓存流在close()的时候会自动flush()

#10


建议你参考FileChannel.transferTo(WritableChannel),一行搞定的事!

#11


引用 9 楼 u010918104 的回复:
@csdngameasm  也可以像8楼这样 buffo.close()因为缓存流在close()的时候会自动flush()
1.我用的是MacOSX笔记本,用文本文件测试的时候,会显示编码为Unicode,无法打开,所以我发现了编码被改变的问题,如果大家用的是windows,可能因为兼容做的好,没有提示,反倒发现不了问题了。2.每次复制出来的文件正好4M,不管源文件多大,正如你说的buffo是4096k缓存,是这样吗?

#12


引用 11 楼 csdngameasm 的回复:
Quote: 引用 9 楼 u010918104 的回复:

@csdngameasm  也可以像8楼这样 buffo.close()因为缓存流在close()的时候会自动flush()
1.我用的是MacOSX笔记本,用文本文件测试的时候,会显示编码为Unicode,无法打开,所以我发现了编码被改变的问题,如果大家用的是windows,可能因为兼容做的好,没有提示,反倒发现不了问题了。2.每次复制出来的文件正好4M,不管源文件多大,正如你说的buffo是4096k缓存,是这样吗?

我是WIN7的,编码的问题因为我没在mac上试过,不过我觉得既然我用这程序能复制txt word 和jpg,就是说单纯在流中的都是纯数据,至于编码和解码是io类内部的事情。从结果看复制的附件和原件是一样的。你说缓存大小这个其实是可以测试的你在new BuffOutoutStream(FlieOutputStream out,int size)就可以了。我说的这里4m是可能缺少4m的数据,但是你说你只生成4m的文件我刚刚试了下用你这段复制一个33m的东西 还是33m。这点我也挺奇怪的,要不你找个win系统试下。。。

#13


如果你觉得是编码问题的话,你可以试试用DataOutputStream输出看看,这个类是能选输出编码的格式的你可以选writeBytes()或者writeUTF()不过参数是String 需要对应使用DataInputStream,或者把输入流的数据转化成字符(有点复杂需要知道编码规则);看看结果是不是不一样

#14


你们好纠结!

package test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;

public class CopyFile{
  public static final void copy(File src,File dst) throws IOException{
    FileInputStream fis=new FileInputStream(src);
    FileChannel in=fis.getChannel();
    FileOutputStream fos=new FileOutputStream(dst);
    FileChannel out=fos.getChannel();
    in.transferTo(0,in.size(),out);
    fos.close();
    fis.close();
  }

  public static final void copy(String src,String dst) throws IOException{
    copy(new File(src),new File(dst));
  }

  public static void main(String...args) throws IOException{
    copy("...","...");
  }
}

#15


引用 13 楼 u010918104 的回复:
如果你觉得是编码问题的话,你可以试试用DataOutputStream输出看看,这个类是能选输出编码的格式的你可以选writeBytes()或者writeUTF()不过参数是String 需要对应使用DataInputStream,或者把输入流的数据转化成字符(有点复杂需要知道编码规则);看看结果是不是不一样


引用 14 楼 zoeg 的回复:
你们好纠结!

package test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;

public class CopyFile{
  public static final void copy(File src,File dst) throws IOException{
    FileInputStream fis=new FileInputStream(src);
    FileChannel in=fis.getChannel();
    FileOutputStream fos=new FileOutputStream(dst);
    FileChannel out=fos.getChannel();
    in.transferTo(0,in.size(),out);
    fos.close();
    fis.close();
  }

  public static final void copy(String src,String dst) throws IOException{
    copy(new File(src),new File(dst));
  }

  public static void main(String...args) throws IOException{
    copy("...","...");
  }
}


好的,我再试试,非常谢谢两位相助,初来论坛,诸多不懂,没有找到给分选项,抱歉,等我找到会把分给两位。