【Java中IO流】OutputStreamWriter的用法

dabing69221 2013-11-28 10:19:11
最近复习了以下java的io流,发现有两个转换流, 分别为: InputStreamReader OutputStreamWriter , OutputStreamWriter是将输入的字符流变为字节流, 我写了一个例子,但怎么行不通? 麻烦大家看一下:

public class SwitchWriter
{
public static void main(String[] args) throws IOException
{

InputStream input = new FileInputStream(new File("D:\\杂乱\\头像.jpg"));

StringBuffer buff = new StringBuffer();
byte[] img = new byte[1024];
while (input.read(img) != -1)
{
buff.append(new String(img));
}

//生成图片失败,这时怎么回事啊?
OutputStreamWriter output = new OutputStreamWriter(
new FileOutputStream("D:\\杂乱\\头像_new.jpg"));

String str = buff.toString();
output.write(str, 0, str.length());

output.flush();
output.close();
input.close();
}
}
...全文
372 21 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
dabing69221 2013-11-29
  • 打赏
  • 举报
回复
引用 7 楼 HarderXin 的回复:
我也帮楼主修改了一下代码:
package com.harderxin.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class SwitchWriter
{
    public static void main(String[] args) throws IOException
    {

        InputStream input = new FileInputStream(new File("C:\\local.png"));
        OutputStream output = 
                new FileOutputStream("C:\\local_new.png");

        byte[] img = new byte[1024];
        while (input.read(img) != -1)
        {
            output.write(img, 0, img.length);
        }

        output.flush();
        output.close();
        input.close();
    }
}

楼主的问题所在应该是输入流是FileInputStream,而输出流为OutputStreamWriter吧,不一致,输入流和输出流应该一致,这样建立起来的管道才能匹配!!
这个是问题所在!这里的输入流应该使用InputStreamReader ,这样才能与输出流OutputStream相对应。 今天,自己把java.io.* 下的所有类都反编译了一下,发现 其实“字符流就是字节流的一个包装类而已”,为什么这么说那? 例如:在InputStreamReader类中调用reader()方法时,其实底层就是调用的InputStream.read()的方法 , 在OutputStreamWriter类中调用write()方法时,其底层就是调用的OutputStream.write()方法; 如果这样分析的话: 现在在看看JDK API上的解释:OutputStreamWriter 是字符流通向字节流的桥梁。通过查看源码我们知道使用字符流OutputStreamWriter.write()其实就是调用字节流OutputStream.write()方法, 到此,我们明白了其实这里所说的“字符流通向字节流的桥梁” 其实,就是 “当我们使用OutputStreamWrite字符流写数据时,它会根据指定的编码方式,将这些输出的字符转换为字节,然后通过调用字节流OutputStream.write()写出数据”! 以上这些东西,是我查看源码得到的信息,建议大家没事多看看源码,我这网上找到了一篇 关于Java IO流的详细介绍 http://www.blogjava.net/zhangchao/archive/2011/05/26/351051.html 估计你看完以后 会对Java IO流有一个新的看法!!!
dabing69221 2013-11-29
  • 打赏
  • 举报
回复
引用 19 楼 HarderXin 的回复:
图片文件的原始文件为字节流文件,用字符流去操作不合适,如果你操作的是txt文件,会得到你想要的结果,我也尝试过了,这是我针对你的这些问题的一些总结,可以去看看,http://blog.csdn.net/harderxin/article/details/17019755
谢谢 ,看来,转换流 还是不能直接操作 二进制 文件啊,算了,还是使用InputStream吧!
dabing69221 2013-11-29
  • 打赏
  • 举报
回复
我看了,你写的博客中与我想的一致。但是,有点纳闷的是“字符流底层就是调用的字节流来进行写入/输出的”
程序员Monkey 2013-11-29
  • 打赏
  • 举报
回复
图片文件的原始文件为字节流文件,用字符流去操作不合适,如果你操作的是txt文件,会得到你想要的结果,我也尝试过了,这是我针对你的这些问题的一些总结,可以去看看,http://blog.csdn.net/harderxin/article/details/17019755
dabing69221 2013-11-29
  • 打赏
  • 举报
回复
我改了一下代码还是不行,是不是内部转换时有问题啊?

public class SwitchWriter {
	public static void main(String[] args) throws IOException {

		InputStreamReader input = new InputStreamReader(new FileInputStream(
				new File("E:\\娱乐\\图片\\我的收藏\\头像\\头像.gif")), "GBK");

		OutputStreamWriter output = new OutputStreamWriter(
				new FileOutputStream(new File(
						"E:\\娱乐\\图片\\我的收藏\\头像\\头像_new.gif")), "GBK");
		int img;
		while ((img = input.read()) != -1) {
			output.write(img);
		}

		output.flush();

		output.close();
		input.close();

	}
}
白开水MD5 2013-11-28
  • 打赏
  • 举报
回复
在字节和字符转换的时候可能会有问题 byte[] img = new byte[1024]; while (input.read(img) != -1) { buff.append(new String(img));//最后一次读取的时候byte可能没读满,所以比实际长度要大 } 这样写的话,新生成的文件大小与原文件不一样, 如果把byte数组的长度改为1的话,文件的大小就一样了,但新生成的文件还是打不开 所以可能在字符转字节的时候又出现问题了,这可应该和OutputStreamWriter有关系
dabing69221 2013-11-28
  • 打赏
  • 举报
回复
请问大家都没有用过OutputStreamWriter吗? JDK API 上说: OutputStreamWriter 是字符流通向字节流的桥梁 ?
wuer0520 2013-11-28
  • 打赏
  • 举报
回复
其实楼主的问题就是楼主两个管道不同!一个是字节流,一个是字符流,如果楼主只想单纯的练字节流转字符流,那么不如练习下从文件中读取文字!
dabing69221 2013-11-28
  • 打赏
  • 举报
回复
引用 5 楼 ysjian_pingcx 的回复:
看到楼主的分享了,我之前在学习流的时候也遇到过很多困惑,现在有些经验了跟楼主分享一下。 通常操作多媒体文件,流中是以二进制的格式进行的,所以建议使用字节流来操作,楼主的方式忽略了一下节点: 1.读的时候使用字节流,写的时候用的是字节转换流,这样的转换过程会发生问题的。 2.读的时候每一次往img数组中读入,然后添加的StringBuffered中的时候,最后一次有可能没有读满数组,所以会导致多余的字节,同时你是否也发现复制后的文件变大了。 我给楼主分享一版代码,希望对你有帮助:
public class SwitchWriter {
	public static void main(String[] args) {
		try {
			copy("E:\\login_icon.png", "E:\\test.png");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 复制文件,使用字节流
	 * 
	 * @param sourcePath
	 * @param targetPath
	 * @throws IOException
	 */
	public static void copy(String sourcePath, String targetPath)
			throws IOException {
		FileInputStream fis = new FileInputStream(sourcePath);
		BufferedInputStream bis = new BufferedInputStream(fis);

		FileOutputStream fos = new FileOutputStream(targetPath);
		BufferedOutputStream bos = new BufferedOutputStream(fos);

		byte[] value = new byte[1024];
		int len = -1;
		while ((len = bis.read(value)) != -1) {
			bos.write(value, 0, len);
		}
		bos.close();
		bis.close();
	}
}
最后有几点我的体会: 1.操作非文本的文件的时候使用字节流,为了提高效率,建议使用字节包装流,就是BufferInputStream 2.读入和写出用的流尽量保持一致。 祝楼主学习进步,加油!
这点我知道,我就是想试一试,这个OutputStreamWriter是怎么把字符流转换为字节流的?
dabing69221 2013-11-28
  • 打赏
  • 举报
回复
引用 10 楼 zzq19860626 的回复:
图片文件读写怎么能用字符流呢?
字符流转换为字节流了
张自强 2013-11-28
  • 打赏
  • 举报
回复
图片文件读写怎么能用字符流呢?
dabing69221 2013-11-28
  • 打赏
  • 举报
回复
引用 6 楼 a470577391 的回复:
[quote=引用 4 楼 dabing69221 的回复:] [quote=引用 2 楼 a470577391 的回复:] OutputStreamWriter output = new OutputStreamWriter( new FileOutputStream("D:\\杂乱\\头像_new.jpg")); String str = buff.toString(); output.write(str, 0, str.length()); 写入的是字符,所以生成图片失败
这里不是应经 把字符流转换为字节流了吗, OutputStreamWriter output = new OutputStreamWriter( new FileOutputStream("D:\\杂乱\\头像_new.jpg"));[/quote] 这个转换可能不是这样理解的吧,你看这里output.write(str, 0, str.length());,写入的明显是字符[/quote] OutputStreamWriter接收的是字符流,会使用特定的编码方式将字符流转换为字节流,然后写入顶层的输出流,建议你看反编译一下OutputStreamWriter的源代码,自己看看就知道了!
白开水MD5 2013-11-28
  • 打赏
  • 举报
回复
引用 4 楼 dabing69221 的回复:
[quote=引用 2 楼 a470577391 的回复:] OutputStreamWriter output = new OutputStreamWriter( new FileOutputStream("D:\\杂乱\\头像_new.jpg")); String str = buff.toString(); output.write(str, 0, str.length()); 写入的是字符,所以生成图片失败
这里不是应经 把字符流转换为字节流了吗, OutputStreamWriter output = new OutputStreamWriter( new FileOutputStream("D:\\杂乱\\头像_new.jpg"));[/quote] 不好意思,是我理解错了
程序员Monkey 2013-11-28
  • 打赏
  • 举报
回复
我也帮楼主修改了一下代码:
package com.harderxin.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class SwitchWriter
{
    public static void main(String[] args) throws IOException
    {

        InputStream input = new FileInputStream(new File("C:\\local.png"));
        OutputStream output = 
                new FileOutputStream("C:\\local_new.png");

        byte[] img = new byte[1024];
        while (input.read(img) != -1)
        {
            output.write(img, 0, img.length);
        }

        output.flush();
        output.close();
        input.close();
    }
}

楼主的问题所在应该是输入流是FileInputStream,而输出流为OutputStreamWriter吧,不一致,输入流和输出流应该一致,这样建立起来的管道才能匹配!!
白开水MD5 2013-11-28
  • 打赏
  • 举报
回复
引用 4 楼 dabing69221 的回复:
[quote=引用 2 楼 a470577391 的回复:] OutputStreamWriter output = new OutputStreamWriter( new FileOutputStream("D:\\杂乱\\头像_new.jpg")); String str = buff.toString(); output.write(str, 0, str.length()); 写入的是字符,所以生成图片失败
这里不是应经 把字符流转换为字节流了吗, OutputStreamWriter output = new OutputStreamWriter( new FileOutputStream("D:\\杂乱\\头像_new.jpg"));[/quote] 这个转换可能不是这样理解的吧,你看这里output.write(str, 0, str.length());,写入的明显是字符
  • 打赏
  • 举报
回复
看到楼主的分享了,我之前在学习流的时候也遇到过很多困惑,现在有些经验了跟楼主分享一下。 通常操作多媒体文件,流中是以二进制的格式进行的,所以建议使用字节流来操作,楼主的方式忽略了一下节点: 1.读的时候使用字节流,写的时候用的是字节转换流,这样的转换过程会发生问题的。 2.读的时候每一次往img数组中读入,然后添加的StringBuffered中的时候,最后一次有可能没有读满数组,所以会导致多余的字节,同时你是否也发现复制后的文件变大了。 我给楼主分享一版代码,希望对你有帮助:
public class SwitchWriter {
	public static void main(String[] args) {
		try {
			copy("E:\\login_icon.png", "E:\\test.png");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 复制文件,使用字节流
	 * 
	 * @param sourcePath
	 * @param targetPath
	 * @throws IOException
	 */
	public static void copy(String sourcePath, String targetPath)
			throws IOException {
		FileInputStream fis = new FileInputStream(sourcePath);
		BufferedInputStream bis = new BufferedInputStream(fis);

		FileOutputStream fos = new FileOutputStream(targetPath);
		BufferedOutputStream bos = new BufferedOutputStream(fos);

		byte[] value = new byte[1024];
		int len = -1;
		while ((len = bis.read(value)) != -1) {
			bos.write(value, 0, len);
		}
		bos.close();
		bis.close();
	}
}
最后有几点我的体会: 1.操作非文本的文件的时候使用字节流,为了提高效率,建议使用字节包装流,就是BufferInputStream 2.读入和写出用的流尽量保持一致。 祝楼主学习进步,加油!
dabing69221 2013-11-28
  • 打赏
  • 举报
回复
引用 2 楼 a470577391 的回复:
OutputStreamWriter output = new OutputStreamWriter( new FileOutputStream("D:\\杂乱\\头像_new.jpg")); String str = buff.toString(); output.write(str, 0, str.length()); 写入的是字符,所以生成图片失败
这里不是应经 把字符流转换为字节流了吗, OutputStreamWriter output = new OutputStreamWriter( new FileOutputStream("D:\\杂乱\\头像_new.jpg"));
白开水MD5 2013-11-28
  • 打赏
  • 举报
回复
OutputStreamWriter output = new OutputStreamWriter( new FileOutputStream("D:\\杂乱\\头像_new.jpg")); String str = buff.toString(); output.write(str, 0, str.length()); 写入的是字符,所以生成图片失败
dabing69221 2013-11-28
  • 打赏
  • 举报
回复
我想知道字符流转字节流,不是字节流的输入输出,虽然,你回答的不对,但还是要谢谢你!
wuer0520 2013-11-28
  • 打赏
  • 举报
回复
楼主虽然不不知道你代码错在哪,但是我帮你写了一个

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class SwitchWriter {
    public static void main(String[] args) {
 
        FileInputStream input = null;
        FileOutputStream output = null;
		try {
			input = new FileInputStream(new File("D:\\杂乱\\头像.jpg"));
			output = new FileOutputStream("D:\\杂乱\\头像_new.jpg");
		    int a;
		    while ((a = input.read()) != -1) {
		          output.write(a);
		    }
		    output.flush();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
	        try {
				output.close();
				input.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
    }
}
加载更多回复(1)

62,634

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧