一直以为关闭流就可以让read返回,没想到不一定,还和流的类型有关

本文通过两个示例探讨了不同类型的输入流在进行read操作时的行为差异:一种类型的流在read时会占用流锁,导致close操作阻塞;而另一种类型如Socket流则可以在read时被关闭,使read操作能够返回。
部署运行你感兴趣的模型镜像

这个类型的流在read时,会占用流的锁,导致close阻塞。例子如下

public class Test {

 /**
  * @param args
  * @throws IOException
  */
 public static void main(String[] args) throws IOException {
  
  Process process = Runtime.getRuntime().exec("notepad");
  final InputStream input = process.getInputStream();
  
  Thread thread = new Thread(new Runnable(){

   @Override
   public void run() {
   
    try {
     System.out.println("read");
     input.read();
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
   
  });
  thread.start();
  
  System.in.read();
  
  System.out.println("close");
  input.close();
  
  System.out.println("over");
 }

}

 

Socket类型的流就可以在read的时候close,这样read就可以返回了。

public class Main {

 /**
  * @param args
  * @throws IOException
  * @throws UnknownHostException
  */
 public static void main(String[] args) throws UnknownHostException, IOException {
  
  Socket s = new Socket("127.0.0.1", 20012);
  final InputStream input = s.getInputStream();
  
  Thread th = new Thread(new Runnable(){

   @Override
   public void run() {
    
    try {
     input.read();
     System.out.println("read return");
    } catch (IOException e) {
     e.printStackTrace();
    }
    
   }
   
  });
  th.start();
  
  System.in.read();
  
  input.close();
  
  System.out.println("over");
 }

}

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

<think>好的,我现在需要回答用户关于Java字节字符read()方法返回值类型区别的问题。根据用户提供的引用内容,我需要先整理这些信息,并结合之前的回答来给出准确且清晰的解释。 首先,用户的问题明确询问的是read()方法的返回值类型区别。根据引用[3]中提到,字节read()返回0-255的int值,而字符read()同样返回int,但范围更大,可以处理如汉字这样的多字节字符。引用[4]提到字节处理的是8位字节,而字符处理的是16位的Unicode字符。此外,用户之前的回答中可能已经涉及了字节字符的基本区别,比如处理数据类型编码方式的不同。 接下来,我需要确认字节字符read()方法的具体定义。例如,FileInputStream的read()方法每次读取一个字节,返回0到255的int,而FileReader的read()方法读取一个字符(可能由多个字节组成),返回0到65535的int,或者-1表示结束。 同时要注意用户可能存在的误区,比如认为字符返回的是char类型,但实际上两者都返回int,只是处理的数据单位不同。另外,需要解释为什么返回值是int而不是byte或char,可能是因为需要-1作为结束标记,而byte的范围不足以表示0-255以外的值。 最后,结合引用中的例子解释,结构清晰地分点说明两者的区别,并确保引用正确的来源。例如,引用[3]说明字节处理汉字的问题,引用[4]说明字节字符的数据单位差异。</think>#### 一、字节与字符 `read()` 方法返回值对比 | **对比维度** | **字节(如 `FileInputStream`)** | **字符(如 `FileReader`)** | |--------------------|-----------------------------------------------------|-------------------------------------------------| | **返回值类型** | `int` | `int` | | **数据单位** | 8 位(1 字节) | 16 位(1 个 Unicode 字符,可能对应多个字节)[^4] | | **有效值范围** | 0-255(无符号字节值) | 0-65535(Unicode 字符范围)[^3] | | **结束标志** | 返回 `-1` 表示结束 | 返回 `-1` 表示结束 | | **典型使用场景** | 二进制文件(图片、视频等) | 文本文件(含多字节字符如汉字)[^3] | #### 二、具体差异解析 1. **数据单位的本质区别** - **字节**:直接读取原始字节(8 位),不涉及字符编码转换。例如读取图片时,返回的 `int` 值表示一个字节的无符号数值。 ```java FileInputStream fis = new FileInputStream("image.jpg"); int byteValue = fis.read(); // 返回 0-255 或 -1 ``` - **字符**:自动按编码规则(如 UTF-8)将字节转换为字符(16 位 Unicode)。例如读取中文文本时,返回的 `int` 值对应一个完整字符的码点。 ```java FileReader fr = new FileReader("text.txt"); int charCode = fr.read(); // 返回汉字 Unicode 码点(如 20013 对应 '中') ``` 2. **返回值范围的意义** - 字节返回 `0-255`:确保能覆盖一个字节的所有可能值(`byte` 类型范围是 `-128~127`,用 `int` 避免符号问题)[^3]。 - 字符返回 `0-65535`:覆盖基本多语言平面(BMP)的 Unicode 字符,超出此范围的字符(如 emoji)需用代理对处理[^4]。 3. **编码处理差异** - 字节直接操作原始字节,需手动处理编码(如 `new String(bytes, "UTF-8")`)。 - 字符内部自动完成编码转换,通过 `InputStreamReader` 可指定编码(如 UTF-8、GBK)[^1]。 #### 三、示例代码对比 **字节读取文件**(逐个字节处理): ```java try (FileInputStream fis = new FileInputStream("data.bin")) { int byteData; while ((byteData = fis.read()) != -1) { byte b = (byte) byteData; // 转换为有符号字节 System.out.println("Read byte: " + b); } } ``` **字符读取文件**(逐个字符处理): ```java try (FileReader fr = new FileReader("text.txt")) { int charCode; while ((charCode = fr.read()) != -1) { char ch = (char) charCode; // 转换为 Unicode 字符 System.out.println("Read character: " + ch); } } ``` #### 四、选择建议 - **优先使用字节**:处理非文本文件(如图像、压缩包)或需要直接控制字节的场景[^4]。 - **优先使用字符**:处理文本文件(尤其是含多字节字符时),避免手动处理编码问题[^3]。 #### 五、常见误区 - **误区**:认为字符返回 `char` 类型。 **正解**:字符 `read()` 返回 `int`,需强制转换到 `char`,但 `int` 类型可完整表示 Unicode 码点[^3]。 - **误区**:字节无法处理文本文件。 **正解**:字节可处理文本,但需额外处理编码转换(如通过 `new String(bytes, StandardCharsets.UTF_8)`)[^1]。 --相关问题--: 1. 如何通过字节正确读取包含汉字的文本文件? 2. Java 中 `BufferedReader` 与 `FileReader` 在处理字符时有何性能差异? 3. 为什么处理二进制文件时使用字符会导致数据损坏?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值