Java 教程 在线

1361Java Scanner 类

输入的时候字符都是可见的,所以Scanner类不适合从控制台读取密码。从Java SE 6开始特别引入了Console类来实现这个目的。若要读取一个密码,可以采用下面这段代码:

Console cons = System.console();
String username = cons.readline("User name: ");
char[] passwd = cons.readPassword("Password: ");

为了安全起见,返回的密码存放在一维字符数组中,而不是字符串中。在对密码进行处理之后,应该马上用一个填充值覆盖数组元素。

采用Console对象处理输入不如采用Scanner方便。每次只能读取一行输入,而没有能够读取一个单词或者一个数值的方法。

1360Java Stream、File、IO

BufferedReader 是支持同步的,而 Scanner 不支持。如果我们处理多线程程序,BufferedReader 应当使用。

BufferedReader 相对于 Scanner 有足够大的缓冲区内存。

Scanner 有很少的缓冲区(1KB 字符缓冲)相对于 BufferedReader(8KB字节缓冲),但是这是绰绰有余的。

BufferedReader 相对于 Scanner 来说要快一点,因为 Scanner 对输入数据进行类解析,而 BufferedReader 只是简单地读取字符序列。

1359Java Stream、File、IO

FileOutputStream 读写文件举例中出现乱码, 跟字符集编码无关, 是由于读写的格式不同导致的。

// 读写文件, 以二进制读写, 有乱码, 是由于输入输出格式转换的原因, 和字符集编码方式无关
public static void main(String[] args) {
    try { 
        byte[] bWrite = {11, 21, 3, 40, 5 };    
        OutputStream os = new FileOutputStream("./out/test.txt");   
        for (int x = 0; x < bWrite.length; ++x) {  
            os.write(bWrite[x]);  
        }       
        os.close();   
        InputStream is = new FileInputStream("./out/test.txt");      
        int size = is.available();    
        for (int x = 0; x < size; ++x) {   
            System.out.print((byte) is.read() + " ");    //强转为byte类型就好了  
        }  
        is.close();   
    } catch (IOException e) {  
        System.out.print("Exception");
    }
}

1358Java Stream、File、IO

有时需要列出目录下指定类型的文件,例如:. java、. txt 等扩展名的文件。可以使用File类的下述两个方法,列出指定类型的文件:

  • 1、public String[ ] list(FilenameFilter obj) 该方法用字符串的形式返回目录下的指定类型的所有文件
  • 2、public File[ ] listFile(FilenameFilter obj) 该方法用 File 对象形式返回目录下的指定类型的所有文件

上述两个方法的参数 FilenameFilter 是一个接口,该接口有一个方法:

public boolean accept(File f,String name);

File 对象 f 调用 list 方法时,需向该方法传递一个实现 FilenameFilter 接口的对象,list 方法执行时,参数 obj 不断回调接口方法accept(File f,String name),该方法中的参数 f 为,调用 list 的当前目录,参数 name 被实例化为当前目录中的一个文件名,当接口方法返回 true 时,list 方法就将名字为 name 的文件存放到返回的数组中。

import java.io.*;

public class Filelei implements FilenameFilter {//此次使用本类作为接口

    /**
     * @param args
     */
    public void f(){
        File f=new File("E:\\Myworkspace\\08\\src");
        String []filename=f.list();//以字符串的形式,先列出当前目录下所有文件看一下(有什么类型的文件)
        for(int i=0;i<filename.length;i++){
            System.out.println(filename[i]);
        }
        System.out.println("********************************");
        String []fname=f.list(this);
        for(int i=0;i<fname.length;i++){
            System.out.println(fname[i]);
        }
        
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new Filelei().f();
        
    }

    @Override
    public boolean accept(File f, String name) {//重写接口方法
        // TODO Auto-generated method stub
        return name.endsWith(".java");//返回当前目录下以.java结尾的文件
    }
}

运行结果:

A.java
B.java
C.java
J1.java
J2.java
J3.java
我是 DOC 文档.doc
我是 XLS 工作表.xls
我是文本文档.txt
********************************
A.java
B.java
C.java
J1.java
J2.java
J3.java

1357Java Stream、File、IO

自己写了一个简单的小程序用来剪辑特定长度的音频,并将它们混剪在一起,大体思路是这样的:

1. 使用 FileInputStream 输入两个音频

2. 使用 FileInputStream的skip(long n) 方法跳过特定字节长度的音频文件,比如说:输入 skip(1024*1024*3),这样就能丢弃掉音频文件前面的 3MB 的内容。

3. 截取中间特定长度的音频文件:每次输入 8KB 的内容,使用 count 记录输入次数,达到设置的次数就终止音频输入。比如说要截取 2MB 的音频,每次往输入流中输入 8KB 的内容,就要输入 1024*2/8 次。

4. 往同一个输出流 FileOutputStream 中输出音频,并生成文件,实现音频混合。

音乐素材下载: Download

下面就给出相关代码:

public class MusicCompound 
{
    public static void main(String args[])
    {
        FileOutputStream fileOutputStream = null;
        FileInputStream fileInputStream = null;
        String fileNames[] = {"E:/星月神话.mp3","E:/我只在乎你.mp3"};
        //设置byte数组,每次往输出流中传入8K的内容
        byte by[] = new byte[1024*8];
        try
        {
            fileOutputStream = new FileOutputStream("E:/合并.mp3");
            for(int i=0;i<2;i++)
            {
                int count = 0;
                fileInputStream = new FileInputStream(fileNames[i]);
                //跳过前面3M的歌曲内容
                fileInputStream.skip(1024*1024*3);
                while(fileInputStream.read(by) != -1)
                {                    
                    fileOutputStream.write(by);
                    count++;
                    System.out.println(count);
                    //要截取中间2MB的内容,每次输入8k的内容,所以输入的次数是1024*2/8
                    if(count == (1024*2/8))
                    {
                        break;
                    }
                }
            }
        }
        catch(FileNotFoundException e)
        {
            e.printStackTrace();
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
        finally
        {
            try
            {
                //输出完成后关闭输入输出流
                fileInputStream.close();
                fileOutputStream.close();
            } 
            catch(IOException e)
            {
                e.printStackTrace();
            }
        }
    }
}