java中的io系统总结.(转)

java中的io中的(input/output)stream无非就是包括基于字符的stream、基于字节的stream和把字节导向的stream转换
字符为导向的stream的stream。(很难理解么?)
以字节为导向的stream------InputStream/OutputStream
InputStream 和 OutputStream是两个abstact类,对于字节为导向的stream都扩展这两个鸡肋(基类^_^);
--InputStream
ByteArrayInputStream -- 把内存中的一个缓冲区作为InputStream使用.

construct---ByteArrayInputStream(byte[])创建一个新字节数组输入流,它从指定字节数组中读取数据。
---ByteArrayInputStream(byte[], int, int) 创建一个新字节数组输入流,它从指定字节数组中读取数据。
---mark::该字节数组未被复制。

StringBufferInputStream -- 把一个String对象作为InputStream .
注释:不推荐使用 StringBufferInputStream 方法。 此类不能将字符正确的转换为字节。
同 JDK 1.1 版中的类似,从一个串创建一个流的最佳方法是采用 StringReader 类。 

construct---StringBufferInputStream(String) 据指定串创建一个读取数据的输入流串。

FileInputStream -- 把一个文件作为InputStream,实现对文件的读取操作 

construct---FileInputStream(File) 创建一个输入文件流,从指定的 File 对象读取数据。
---FileInputStream(FileDescriptor) 创建一个输入文件流,从指定的文件描述器读取数据。
---FileInputStream(String) 创建一个输入文件流,从指定名称的文件读取数据。

method ---- read() 从当前输入流中读取一字节数据。 
read(byte[]) 将当前输入流中 b.length 个字节数据读到一个字节数组中。 
read(byte[], int, int) 将输入流中 len 个字节数据读入一个字节数组中。

PipedInputStream:实现了pipe的概念,主要在线程中使用. 管道输入流是指一个通讯管道的接收端。
一个线程通过管道输出流发送数据,而另一个线程通过管道输入流读取数据,
这样可实现两个线程间的通讯。

PipedInputStream() 创建一个管道输入流,它还未与一个管道输出流连接。 
PipedInputStream(PipedOutputStream) 创建一个管道输入流, 它已连接到一个管道输出流。 

SequenceInputStream:把多个InputStream合并为一个InputStream .“序列输入流”类允许应用程序把几个输入流连续地合并起来,
并且使它们像单个输入流一样出现。每个输入流依次被读取,直到到达该流的末尾。
然后“序列输入流”类关闭这个流并自动地切换到下一个输入流。 
SequenceInputStream(Enumeration) 创建一个新的序列输入流,并用指定的输入流的枚举值初始化它。 
SequenceInputStream(InputStream, InputStream) 创建一个新的序列输入流,初始化为首先 读输入流 s1, 然后读输入流 s2。

--OutputSteam

ByteArrayOutputStream:把信息存入内存中的一个缓冲区中.该类实现一个以字节数组形式写入数据的输出流。
当数据写入缓冲区时,它自动扩大。用 toByteArray() 和 toString() 能检索数据。 

construct --- ByteArrayOutputStream() 创建一个新的字节数组输出流。
--- ByteArrayOutputStream() 创建一个新的字节数组输出流。 
--- ByteArrayOutputStream(int) 创建一个新的字节数组输出流,并带有指定大小字节的缓冲区容量。 
toString(String) 根据指定字符编码将缓冲区内容转换为字符串,并将字节转换为字符。 
write(byte[], int, int) 将指定字节数组中从偏移量 off 开始的 len 个字节写入该字节数组输出流。 
write(int) 将指定字节写入该字节数组输出流。 
writeTo(OutputStream) 用 out.write(buf, 0, count) 调用输出流的写方法将该字节数组输出流的全部内容写入指定的输出流参数。 

FileOutputStream:文件输出流是向 File 或 FileDescriptor 输出数据的一个输出流。

FileOutputStream(File) 创建一个文件输出流,向指定的 File 对象输出数据。 
FileOutputStream(FileDescriptor) 创建一个文件输出流,向指定的文件描述器输出数据。 
FileOutputStream(String) 创建一个文件输出流,向指定名称的文件输出数据。 
FileOutputStream(String, boolean) 用指定系统的文件名,创建一个输出文件。

PipedOutputStream:管道输出流是指一个通讯管道的发送端。 一个线程通过管道输出流发送数据,
而另一个线程通过管道输入流读取数据,这样可实现两个线程间的通讯。

PipedOutputStream() 创建一个管道输出流,它还未与一个管道输入流连接。 
PipedOutputStream(PipedInputStream) 创建一个管道输出流,它已连接到一个管道输入流。


以字符为导向的stream Reader/Writer

以Unicode字符为导向的stream,表示以Unicode字符为单位从stream中读取或往stream 中写入信息。
Reader/Writer 为abstact类
以Unicode字符为导向的stream包括下面几种类型:

-- Reader

1) CharArrayReader:与ByteArrayInputStream对应 
CharArrayReader(char[]) 用指定字符数组创建一个 CharArrayReader。
CharArrayReader(char[], int, int) 用指定字符数组创建一个 CharArrayReader。

2) StringReader:与StringBufferInputStream对应 
StringReader(String) 创建一新的串读取者。
3) FileReader:与FileInputStream对应

4) PipedReader:与PipedInputStream对应

-- Writer

1) CharArrayWrite:与ByteArrayOutputStream对应 
2) StringWrite:无与之对应的以字节为导向的stream 
3) FileWrite:与FileOutputStream对应 
4) PipedWrite:与PipedOutputStream对应

两种不现导向的stream之间的转换
InputStreamReader和OutputStreamReader:把一个以字节为导向的stream转换成一个以字符为导向的stream。
一个 InputStreamReader 类是从字节流到字符流的桥梁:它读入字节,并根据指定的编码方式,将之转换为字符流。
使用的编码方式可能由名称指定,或平台可接受的缺省编码方式。

InputStreamReader 的 read() 方法之一的每次调用,可能促使从基本字节输入流中读取一个或多个字节。
为了达到更高效率,考虑用 BufferedReader 封装 InputStreamReader,
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

InputStreamReader(InputStream) 用缺省的字符编码方式,创建一个 InputStreamReader。 
InputStreamReader(InputStream, String) 用已命名的字符编码方式,创建一个 InputStreamReader。

OutputStreamWriter 将多个字符写入到一个输出流,根据指定的字符编码将多个字符转换为字节。 
每个 OutputStreamWriter 合并它自己的 CharToByteConverter, 因而是从字符流到字节流的桥梁。

FilterInputStream、RandomAccessFile 见例子。
ObjectInputStream 、 ObjectOutputStream见另外blog。


Java IO的一般使用原则:

一、按数据来源(去向)分类:
1、是文件: FileInputStream, FileOutputStream, FileReader, FileWriter
2、是byte[]:ByteArrayInputStream, ByteArrayOutputStream
3、是Char[]: CharArrayReader, CharArrayWriter
4、是String: StringBufferInputStream, StringReader, StringWriter
5、网络数据流:InputStream, OutputStream, Reader, Writer

二、按是否格式化输出分:
1、要格式化输出:PrintStream, PrintWriter

三、按是否要缓冲分:
1、要缓冲:BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter

四、按数据格式分:
1、二进制格式(只要不能确定是纯文本的): InputStream, OutputStream及其所有带Stream结束的子类
2、纯文本格式(含纯英文与汉字或其他编码方式);Reader, Writer及其所有带Reader, Writer的子类

五、按输入输出分:
1、输入:Reader, InputStream类型的子类
2、输出:Writer, OutputStream类型的子类

六、特殊需要:
1、从Stream到Reader,Writer的转换类:InputStreamReader, OutputStreamWriter
2、对象输入输出:ObjectInputStream, ObjectOutputStream
3、进程间通信:PipeInputStream, PipeOutputStream, PipeReader, PipeWriter
4、合并输入:SequenceInputStream
5、更特殊的需要:PushbackInputStream, PushbackReader, LineNumberInputStream, LineNumberReader

决定使用哪个类以及它的构造进程的一般准则如下(不考虑特殊需要):
首先,考虑最原始的数据格式是什么: 原则四
第二,是输入还是输出:原则五
第三,是否需要转换流:原则六第1点
第四,数据来源(去向)是什么:原则一
第五,是否要缓冲:原则三 (特别注明:一定要注意的是readLine()是否有定义,有什么比read, write更特殊的输入或输出方法)
第六,是否要格式化输出:原则二

<think>嗯,用户现在遇到了一个JavaFileNotFoundException,错误信息是系统找不到指定的路径“myio\a.txt”。看起来他们之前运行了某个Java程序,试图在myio目录下创建或写入a.txt文件,但失败了。根据之前的对话历史,我之前给他们分析过类似的代码问题,特别是关于目录不存在的情况,并给出了改进建议。现在用户可能遇到了同样的问题,需要再次帮助解决。 首先,我需要确认用户当前的错误信息是否和之前的问题相同。错误信息中的路径是“myio\a.txt”,而之前的例子是“2025_3_1\a.txt”,所以目录不同,但问题本质是一样的:目标目录不存在,导致无法创建文件。用户可能在他们的代码中使用了类似的结构,例如直接创建FileOutputStream而没有先创建目录。 查看错误堆栈跟踪,异常发生在FileOutputStream的构造函数中,具体是在打开文件的时候,这说明Java试图打开文件进行写入时,发现路径中的目录不存在。这一点和之前的分析一致。用户可能没有在代码中添加创建目录的步骤,或者目录权限有问题,但更可能的是目录不存在。 用户提供的错误信息中还提到了加载vcruntime140.dll的Error,这个DLL是Visual C++运行库的一部分,可能跟Java程序本身关系不大,可能是环境问题或者某个本地库依赖的问题。不过,主要的异常还是FileNotFoundException,所以应该先解决路径问题,再看看这个DLL错误是否依然存在。 接下来,我需要分步骤解释错误原因,并提供解决方案。首先,要明确错误原因,然后给出如何创建目录,使用try-with-resources自动关闭流,以及可能的其他改进建议。同时,用户可能不太清楚Java中如何处理文件路径和目录的创建,所以需要详细说明。 另外,用户可能不太明白为什么需要创建目录,或者如何正确使用File类来创建目录。需要给出具体的代码示例,比如使用File.mkdirs()来创建多级目录。同时,提醒他们使用try-with-resources可以避免资源泄漏,确保流被正确关闭,即使在发生异常的情况下。 可能还需要检查用户代码中的路径是否正确,反斜杠是否正确义,或者是否应该使用正斜杠。在Java中,路径分隔符可以使用双反斜杠或者正斜杠,例如“myio/a.txt”可能更跨平台友好。不过,在Windows系统中,反斜杠是标准的,但需要正确义。 最后,关于vcruntime140.dll的错误,可能需要用户安装Visual C++ Redistributable for Visual Studio 2015或更新版本,但这可能与当前的Java文件操作问题无关,可能是一个额外的错误,或者是由于其他依赖引起的。用户可以先解决主要的文件路径问题,再看看这个DLL错误是否仍然存在。如果是环境问题,可能需要单独处理。 总结,用户的当务之急是处理FileNotFoundException,通过创建目录和优化资源管理来解决。然后,如果有必要,再处理DLL加载的问题。</think>$\text{FileNotFoundException}$ 分析及解决方案如下: --- ### 一、错误原因解析 ```java java.io.FileNotFoundException: myio\a.txt (系统找不到指定的路径) ``` - **核心问题**:Java尝试在$\text{myio}$目录下创建/写入$\text{a.txt}$文件时,发现$\text{myio}$目录不存在 - **典型触发场景**: ```java FileOutputStream fos = new FileOutputStream("myio\\a.txt"); // 目录不存在直接操作文件 ``` --- ### 二、解决方案步骤 1. **添加目录创建代码** ```java import java.io.File; public class ByteStreamDemo1 { public static void main(String[] args) { // 先创建目录结构 new File("myio").mkdirs(); // 自动创建多级目录 try (FileOutputStream fos = new FileOutputStream("myio\\a.txt")) { fos.write(97); // 写入内容... } catch (IOException e) { e.printStackTrace(); } } } ``` 2. **路径格式优化建议** - 使用正斜杠跨平台兼容:$\text{"myio/a.txt"}$ - 或动态获取路径分隔符: ```java String separator = File.separator; String path = "myio" + separator + "a.txt"; ``` --- ### 三、改进实践对比 | 问题代码 | 改进代码 | 优势 | |---------|----------|------| | `new FileOutputStream("myio\\a.txt")` | `new File("myio").mkdirs()` + `try-with-resources` | 1. 自动创建目录<br>2. 自动关闭资源<br>3. 异常处理完善 | --- ### 四、附加错误分析 ```text Error: loading: D:\yuze\bin\vcruntime140.dll ``` - **可能原因**:缺少Visual C++运行库 - **解决方案**: 1. 下载安装 [Microsoft Visual C++ Redistributable](https://aka.ms/vs/16/release/vc_redist.x64.exe) 2. 检查环境变量PATH是否包含$\text{D:\yuze\bin}$路径 --- ### 五、最终执行流程 1. 创建$\text{myio}$目录 ✅ 2. 在目录内生成$\text{a.txt}$ ✅ 3. 成功写入字节数据 ✅ 4. 自动释放文件资源 ✅ 建议优先解决目录不存在问题,再验证DLL相关错误是否仍存在。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值