Java中从文件中读取数据用啥函数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java中从文件中读取数据用啥函数相关的知识,希望对你有一定的参考价值。

一:用Scanner可以很好的达到读写文件的作用。

但是学习过程中,由于Scanner的构造函数的参数是InputStream,搞得有点糊涂。后来发现InputStream是一个抽象类,FileInputStream是它的一个子类。而FileInputStream可以以String或File为参数读入文件流,然后用这个FileInputStream对象初始化一个Scanner,如sin。然后就可以像手动输入一样使用sin读入文件中的信息。用sin.hasnext()表示是否读到文件结尾。
对应的可以用PrintStream达到写入文件的效果,它要用一个FileOutputStream(或File file或String filename)作构造函数的参数,然后就可以像在控制台中显示数据一样写入文件。
二:可以用DataInputStream对象实现文件的读入,其构造函数的参数也是InputStream,所以也可以用FileInputStream,读取用DataInputStream.readInt()等即可,DataInputStream.readXX()会抛出EOFException()和IOException()。并且在读到文件结尾时会返回-1。另外用DataInputStream.available()==0表示读到文件结尾。

写入文件可以用DataOutputStream对象,写入可以用DataOutputStream.writeXX(),注意,这些writeXX()都是以二进制的方式写入的,所以直接打开文件显示的是乱码。要显示写入文件中的int等数据,要以String形式读入。虽然显示的是乱码,但是用DataInputStream的readXX()可以以int等类型读入。
参考技术A 给你个例子:
import java.io.*;
public class TestFileReader
public static void main(String[] args)
FileReader fr = null;
int c = 0;
try
fr = new FileReader("d:\\share\\java\\io\\TestFileReader.java");
int ln = 0;
while ((c = fr.read()) != -1)
//char ch = (char) fr.read();
System.out.print((char)c);
//if (++ln >= 100) System.out.println(); ln = 0;

fr.close();
catch (FileNotFoundException e)
System.out.println("找不到指定文件");
catch (IOException e)
System.out.println("文件读取错误");



本回答被提问者和网友采纳
参考技术B 看你读取什么文件,如果是文本的话,直接使用readline() 参考技术C 一般都是转化成流对象接收了,然后再解析

File类和相关API

在 python 中从 TIMIT 数据库中读取 WAV 文件

【中文标题】在 python 中从 TIMIT 数据库中读取 WAV 文件【英文标题】:reading a WAV file from TIMIT database in python 【发布时间】:2017-06-25 16:19:21 【问题描述】:

我正在尝试从 python 中的 TIMIT 数据库中读取一个 wav 文件,但出现错误:

当我使用 wave 时:

wave.Error: file does not start with RIFF id

当我使用 scipy 时:

ValueError: File format b'NIST'... not understood.

当我使用 librosa 时,程序卡住了。 我尝试使用 sox 将其转换为 wav:

cmd = "sox " + wav_file + " -t wav " + new_wav
subprocess.call(cmd, shell=True)

它没有帮助。我看到一个引用包 scikits.audiolab 的旧答案,但它看起来不再受支持。

如何读取这些文件以获取数据的 ndarray?

谢谢

【问题讨论】:

您可以尝试使用 soundfile 模块或任何其他应该支持 NIST 格式的 libsndfile 包装器来读取文件。 【参考方案1】:

您的文件不是 WAV 文件。显然它是一个 NIST SPHERE 文件。来自LDC web page:“许多LDC语料库包含NIST SPHERE格式的语音文件。”根据NIST File Format的描述,文件的前四个字符是NIST。这就是 scipy 错误告诉您的内容:它不知道如何读取以 NIST 开头的文件。

如果您想使用您尝试过的任何库读取文件,我怀疑您必须将convert the file 转换为 WAV。要使用程序 sph2pipe 强制转换为 WAV,请使用命令选项 -f wav(或等效的 -f rif),例如

sph2pipe -f wav input.sph output.wav

【讨论】:

我更新了我的答案,并附上了关于使用 -f wav 的说明。 在当前目录下的所有文件上递归运行它的简单方法是find . -name '*.WAV' -exec sph2pipe -f wav .wav \;。唯一的缺点是您最终会得到以 .WAV.wav 结尾的文件。【参考方案2】:

从命令行发出这个来验证它是否是一个 wav 文件......

xxd -b myaudiofile.wav | head

如果它是 wav 格式,它会显示类似

00000000: 01010010 01001001 01000110 01000110 10111100 10101111  RIFF..
00000006: 00000001 00000000 01010111 01000001 01010110 01000101  ..WAVE
0000000c: 01100110 01101101 01110100 00100000 00010000 00000000  fmt ..
00000012: 00000000 00000000 00000001 00000000 00000001 00000000  ......
00000018: 01000000 00011111 00000000 00000000 01000000 00011111  @...@.
0000001e: 00000000 00000000 00000001 00000000 00001000 00000000  ......
00000024: 01100100 01100001 01110100 01100001 10011000 10101111  data..
0000002a: 00000001 00000000 10000001 10000000 10000001 10000000  ......
00000030: 10000001 10000000 10000001 10000000 10000001 10000000  ......
00000036: 10000001 10000000 10000001 10000000 10000001 10000000  ......

这是另一种显示二进制文件内容的方法,例如 WAV

od -A x -t x1z -v  audio_util_test_file_custom.wav   | head 
000000 52 49 46 46 24 80 00 00 57 41 56 45 66 6d 74 20  >RIFF$...WAVEfmt <
000010 10 00 00 00 01 00 01 00 44 ac 00 00 88 58 01 00  >........D....X..<
000020 02 00 10 00 64 61 74 61 00 80 00 00 00 00 78 05  >....data......x.<
000030 ed 0a 5e 10 c6 15 25 1b 77 20 ba 25 eb 2a 08 30  >..^...%.w .%.*.0<
000040 0e 35 fc 39 cf 3e 84 43 1a 48 8e 4c de 50 08 55  >.5.9.>.C.H.L.P.U<
000050 0b 59 e4 5c 91 60 12 64 63 67 85 6a 74 6d 30 70  >.Y.\.`.dcg.jtm0p<
000060 b8 72 0a 75 25 77 09 79 b4 7a 26 7c 5d 7d 5a 7e  >.r.u%w.y.z&|]Z~<
000070 1c 7f a3 7f ee 7f fd 7f d0 7f 67 7f c3 7e e3 7d  >..........g..~.<
000080 c9 7c 74 7b e6 79 1e 78 1f 76 e8 73 7b 71 d9 6e  >.|t.y.x.v.sq.n<
000090 03 6c fa 68 c1 65 57 62 c0 5e fd 5a 0f 57 f8 52  >.l.h.eWb.^.Z.W.R<

注意 wav 文件以字符 RIFF 开头 这是文件使用 wav 编解码器的强制性指标...如果您的系统(我在 linux 上)没有上述命令行实用程序:xxd 然后使用 any hex editor like wxHexEditor 类似地检查您的 wav 文件以确认您看到 RIFF ...如果没有 RIFF,那么它根本就不是 wav 文件

以下是 wav 格式规范的详细信息

http://soundfile.sapp.org/doc/WaveFormat/

http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html

http://unusedino.de/ec64/technical/formats/wav.html

http://www.drdobbs.com/database/inside-the-riff-specification/184409308

https://www.gamedev.net/articles/programming/general-and-gameplay-programming/loading-a-wave-file-r709

http://www.topherlee.com/software/pcm-tut-wavformat.html

http://www.labbookpages.co.uk/audio/javaWavFiles.html

http://www.johnloomis.org/cpe102/asgn/asgn1/riff.html

http://nagasm.org/ASL/sound05/

【讨论】:

【参考方案3】:

如果您想要一个适用于文件夹内每个 wav 文件的通用代码,请运行:

forfiles /s /m *.wav /c "cmd /c sph2pipe -f wav @file @fnameRIFF.wav"

它搜索每个可以找到的 wav 文件,并创建一个 scipy 和 wave 都可以读取的 wav 文件,名称为 RIFF.wav

【讨论】:

这与 Warren Weckesser 的 sph2pipe 解决方案相辅相成...我本来可以将其作为评论,但我还没有所需的声誉。 find . -name '*.WAV' -exec sph2pipe -f wav .wav \; 如果你不想安装forfiles【参考方案4】:

我编写了一个 python 脚本,它将所有方言的所有说话者所说的 NIST 格式的所有 .WAV 文件转换为 .wav 文件 n 在您的系统上播放。

注意:所有方言文件夹都存在于 ./TIMIT/TRAIN/ 中。您可能需要根据您的项目结构(或者如果您在 Windows 上)更改 dialects_path

from sphfile import SPHFile

dialects_path = "./TIMIT/TRAIN/"

for dialect in dialects:
    dialect_path = dialects_path + dialect
    speakers = os.listdir(path = dialect_path)
    for speaker in speakers:
        speaker_path =  os.path.join(dialect_path,speaker)        
        speaker_recordings = os.listdir(path = speaker_path)

        wav_files = glob.glob(speaker_path + '/*.WAV')

        for wav_file in wav_files:
            sph = SPHFile(wav_file)
            txt_file = ""
            txt_file = wav_file[:-3] + "TXT"

            f = open(txt_file,'r')
            for line in f:
                words = line.split(" ")
                start_time = (int(words[0])/16000)
                end_time = (int(words[1])/16000)
            print("writing file ", wav_file)
            sph.write_wav(wav_file.replace(".WAV",".wav"),start_time,end_time)    

【讨论】:

【参考方案5】:

请使用 sounddevice 和 soundfile 获取 numpy 数组数据(和回放)使用以下代码:

import matplotlib.pyplot as plt
import soundfile as sf
import sounddevice as sd
# https://catalog.ldc.upenn.edu/desc/addenda/LDC93S1.wav
data, fs = sf.read('LDC93S1.wav')
print(data.shape,fs)
sd.play(data, fs, blocking=True)
plt.plot(data)
plt.show()

输出

(46797,) 16000

TIMIT 数据库 wav 文件示例:https://catalog.ldc.upenn.edu/desc/addenda/LDC93S1.wav

【讨论】:

【参考方案6】:

有时这可能是由于提取 7zip 文件的方法不正确造成的。我有一个类似的问题。我通过使用7z x &lt;datasetname&gt;.7z提取数据集解决了这个问题

【讨论】:

以上是关于Java中从文件中读取数据用啥函数的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Java 中从 C DLL 加载和使用结构和函数?

Java 读取Excel 文件存放到MySQL 数据库中,读取Excel 文件方法封装好的。用

在 Swift 中从 json 文件中读取数据的正确方法是啥?

如何在javascript中从json文件中读取数据

如何在python中从txt文件中读取数据[重复]

在 python 中从 TIMIT 数据库中读取 WAV 文件