0

我有一个应用程序,它使用从 Socket InputStream 获取的字节数组创建多个文件。当我只保存一个文件时文件完美保存,但如果我保存一个文件然后重新实例化文件流并保存另一个文件,第一个文件被损坏,第二个文件被完美保存。我在文本编辑器中打开了这两个文件,似乎(大约...)第一个文件的前 1/5 是空格,但第二个文件已满,并且它们都具有相同的大小属性(9,128,731 字节)。以下示例是 senario 的副本,但具有相同的损坏结果:

FileOutputStream outStream;
outStream = new FileOutputStream("/mnt/sdcard/testmp3.mp3");
File file = new File("/mnt/sdcard/test.mp3");
FileInputStream inStream = new FileInputStream(file);
byte[] buffer = new byte[9128731];
inStream.read(buffer);
outStream.write(buffer, 0, buffer.length);
inStream.close();
outStream.flush();
outStream.close();
outStream = null;
outStream = new FileOutputStream("/mnt/sdcard/testmp32.mp3");
outStream.write(buffer, 0, buffer.length);
inStream.close();
outStream.flush();
outStream.close();
outStream = null;

我在常规的 java 应用程序中尝试了这个 EXACT 代码,两个文件都被保存没有问题。有谁知道为什么android会这样做?

任何帮助将不胜感激

4

4 回答 4

5

正如 jtahlborn 提到的,你不能假设它InputStream.read(byte[])总是会读取你想要的字节数。同样,您应该避免使用如此大的字节数组一次写出。至少在没有缓冲的情况下,你可能会溢出一些东西。您可以通过像这样复制文件来处理这些问题并节省一些内存:

File inFile = new File("/mnt/sdcard/test.mp3");
File outFile = new File("/mnt/sdcard/testmp3.mp3");
FileInputStream inStream = new FileInputStream(inFile);
FileOutputStream outStream = new FileOutputStream(outFile);
byte[] buffer = new byte[65536];
int len;
while ((len = inStream.read(buffer)) != -1) {
    outStream.write(buffer, 0, len);
}
inStream.close();
outStream.close();
于 2011-03-27T08:03:39.557 回答
1

我看到了一些可以让您开始调试的潜在问题:

  1. 在关闭输入流之前写入第一个输出流。这有点奇怪。

  2. 您无法使用文本编辑器准确衡量两个二进制文件之间的相似性/差异。您需要在十六进制编辑器(或更好的Audacity)中查看文件

  3. 我会BufferedOutputStream按照 Android 文档的建议使用:http: out = new BufferedOutputStream(new FileOutputStream(file)); //developer.android.com/reference/java/io/FileOutputStream.html

  4. 作为一种调试技术,buffer在第一次写入后打印内容。此外,inStream.read()返回一个int. 我还会将其与此进行比较buffer.length并确保它们相同。无论如何,除非您有充分的理由,否则我只会打电话write(buffer)而不是打电话。write(buffer, 0, buffer.length)

-tjw

于 2011-03-23T03:12:59.953 回答
0

您假设read()调用将读取任意数量的字节。这是不正确的。该方法可以自由读取从 1 到 buffer.length 字节的任何位置。这就是为什么您应该始终使用返回值来确定实际读取了多少字节。那里有很多流教程,它们将向您展示如何正确地从 java 流中读取(即如何完全填充缓冲区)。

于 2011-03-23T03:18:15.290 回答
0

如果有人遇到同样的问题并想知道如何解决它,我发现问题是由我的 SD 卡引起的。我买了一张 32gb 金士顿 sd 卡,就在昨天我决定尝试再次运行相同的代码,接受使用内部存储,一切正常。我还试用了它附带的 2gb SD 卡,它也运行良好。我很高兴知道我的代码运行良好,但有点沮丧,我花了 50 美元买了一张有缺陷的存储卡。感谢大家的意见。

于 2011-03-27T07:50:25.080 回答